hibernate/hibernate-orm · error · IllegalArgumentException

Could not deserialize string to java type: {}

Error message

Could not deserialize string to java type: {}

What it means

JacksonXmlFormatMapper is the FormatMapper Hibernate uses for @JdbcTypeCode(SqlTypes.SQLXML) attributes via jackson-dataformat-xml. This IllegalArgumentException (JacksonXmlFormatMapper.java:163) wraps a JsonProcessingException raised when the stored XML cannot be parsed into the attribute's Java type, including the Map/array paths that depend on the mapper's legacyFormat flag. The stored XML layout for collections and maps changed between Hibernate versions, controlled by hibernate.type.xml_format_mapper.legacy_format.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jackson/JacksonXmlFormatMapper.java:163

					);
					return javaType.wrap( collectionWrapper.value, wrapperOptions );
				}
				else if ( javaType.getJavaTypeClass().isArray() ) {
					final CollectionWrapper<?> collectionWrapper = objectMapper.readValue(
							charSequence.toString(),
							objectMapper.constructType( new ParameterizedTypeImpl( CollectionWrapper.class,
									new Type[] {javaType.getJavaTypeClass().getComponentType()}, null ) )
					);
					return javaType.wrap( collectionWrapper.value, wrapperOptions );
				}
			}
			return objectMapper.readValue(
					charSequence.toString(),
					objectMapper.constructType( javaType.getJavaType() )
			);
		}
		catch (JsonProcessingException 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

  1. If the data was written by an older Hibernate, set hibernate.type.xml_format_mapper.legacy_format=true so the mapper reads the legacy wrapper layout.
  2. Compare a failing column value against the attribute type and fix the data or the mapping so element names/shape match.
  3. Make the target type Jackson-XML friendly: default constructor, @JacksonXmlProperty/@JacksonXmlRootElement names matching the stored XML.
  4. Migrate stored XML with a one-off script when the attribute type changes.
  5. Supply a customized XmlMapper through JacksonXmlFormatMapper(ObjectMapper, legacyFormat) via the hibernate.type.xml_format_mapper setting if you need bespoke handling.

Example fix

// before - rows written by old Hibernate fail to read after upgrade
<persistence ...>
  <properties>
    <property name="hibernate.type.xml_format_mapper" value="jackson-xml"/>
  </properties>

// after - opt into the legacy XML layout for pre-upgrade data
<property name="hibernate.type.xml_format_mapper.legacy_format" value="true"/>
Defensive patterns

Strategy: try-catch

Validate before calling

// After a Hibernate upgrade, sample existing rows and check they parse
XmlMapper xml = XmlMapper.builder().findAndAddModules().build();
for ( String storedXml : sampleColumnValues() ) {
    xml.readValue( storedXml, MyXmlType.class ); // throws early with a clear location
}

Try / catch

try {
    return session.find( Doc.class, id );
} catch ( IllegalArgumentException e ) {
    if ( e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException jpe ) {
        // stored XML does not match attribute type / format version - check jpe.getLocation()
    } else throw e;
}

Prevention

When it happens

Trigger: Loading an entity with a SqlTypes.SQLXML attribute whose column XML is malformed or does not match the attribute type; reading XML written by an older Hibernate version (legacy <Collection><e>... wrapper layout) while running with the new non-legacy default (legacyFormat=false in JacksonXmlFormatMapper.java:58-61); mapping a POJO whose fields do not match the XML element names; attribute types Jackson-XML cannot construct (no default constructor).

Common situations: Upgrading Hibernate across the version that introduced the new XML format and reading pre-existing rows; changing the attribute type (List to Map or vice versa) without migrating stored XML; external systems writing the XML column with a different layout.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/eb4ad48ac862835d. Report an issue: GitHub.