hibernate/hibernate-orm · error · IllegalArgumentException
Could not deserialize string to java type: {}
Error message
Could not deserialize string to java type: {} What it means
XML counterpart of the Jackson 3 mapper, used for @JdbcTypeCode(SqlTypes.XML) attributes: fromString() binds the XML column content with an XmlMapper and wraps any JacksonException as IllegalArgumentException('Could not deserialize string to java type: <type>'). The stored XML does not bind to the mapped Java type — wrong root/element names, collection wrapping mismatch (non-legacy format expects a 'Collection' root with 'e' elements), or value type mismatch.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jackson/Jackson3XmlFormatMapper.java:161
);
return javaType.wrap( collectionWrapper.value, wrapperOptions );
}
else if ( javaType.getJavaTypeClass().isArray() ) {
final CollectionWrapper<?> collectionWrapper = xmlMapper.readValue(
charSequence.toString(),
xmlMapper.constructType( new ParameterizedTypeImpl( CollectionWrapper.class,
new Type[] {javaType.getJavaTypeClass().getComponentType()}, null ) )
);
return javaType.wrap( collectionWrapper.value, wrapperOptions );
}
}
return xmlMapper.readValue(
charSequence.toString(),
xmlMapper.constructType( javaType.getJavaType() )
);
}
catch (JacksonException e) {
throw new IllegalArgumentException( "Could not deserialize string to java type: " + javaType, e );
}
}
@Override
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
if ( javaType.getJavaType() == String.class || javaType.getJavaType() == Object.class ) {
return (String) value;
}
if ( !legacyFormat ) {
if ( Map.class.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
final Type keyType;
final Type elementType;
if ( javaType.getJavaType() instanceof ParameterizedType parameterizedType ) {
keyType = parameterizedType.getActualTypeArguments()[0];
elementType = parameterizedType.getActualTypeArguments()[1];
}
else {
keyType = Object.class;View on GitHub (pinned to fad1729dce)
Solutions
- Compare the stored XML with what Hibernate writes for the same mapping (root element, 'e' items for collections)
- Set hibernate.type.xml_format_mapper.legacy_format=true (or false) to match how the existing data was encoded
- Adjust mapping annotations (@JsonRootName, @JacksonXmlProperty/@JacksonXmlElementWrapper) or transform the stored XML to the expected shape
- Read the cause JacksonException for the exact element/path that failed
Example fix
# before: rows written by an older Hibernate (wrapped collection format), new mapper reads them hibernate.type.xml_format_mapper.legacy_format=false # after: match the reader to the stored format hibernate.type.xml_format_mapper.legacy_format=true
Defensive patterns
Strategy: try-catch
Validate before calling
// check the stored XML binds before mass-loading
static <T> void validateXmlMatches(String xml, tools.jackson.databind.JavaType type,
tools.jackson.dataformat.xml.XmlMapper mapper) {
try {
mapper.readValue(xml, type);
} catch (tools.jackson.core.JacksonException e) {
throw new IllegalArgumentException("XML column incompatible: " + e.getMessage(), e);
}
} Try / catch
try {
MyEntity e = session.find(MyEntity.class, id);
} catch (IllegalArgumentException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("Could not deserialize string to java type")) {
Throwable cause = ex.getCause(); // JacksonException naming element/path
throw new DataQualityException("XML column incompatible with mapping: " + cause.getMessage(), ex);
}
throw ex;
} Prevention
- After Hibernate upgrades, verify hibernate.type.xml_format_mapper.legacy_format matches how existing rows were written
- Keep @JsonRootName / @JacksonXmlProperty annotations in sync with stored element names
- Migrate stored XML deliberately when changing collection mappings (List vs single element)
When it happens
Trigger: Loading an @JdbcTypeCode(SqlTypes.XML) entity when: the root element name does not match the mapping; collections are stored in the other encoding style (the mapper was built with the hibernate.type.xml_format_mapper.legacy_format flag mismatching the data); the XML comes from an external producer with different element names; a field type changed (single element vs List).
Common situations: Migrating Hibernate versions where the default XML collection encoding changed (legacy wrapped vs unwrapped format); consuming external XML not generated by Hibernate; changing the mapped Java type without transforming existing rows.
Related errors
- Could not deserialize string to java type: {}
- Could not serialize object of java type: {}
- Could not deserialize string to java type: {}
- Could not deserialize string to java type: {}
- Could not serialize object of java type: {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/473f6718ab576c64.
Report an issue: GitHub.