hibernate/hibernate-orm · error · IllegalArgumentException
Could not deserialize string to java type: {}
Error message
Could not deserialize string to java type: {} What it means
JaxbXmlFormatMapper is the FormatMapper Hibernate uses for @JdbcTypeCode(SqlTypes.SQLXML) attributes when a jakarta.xml.bind (JAXB) runtime is present (see the JAXBContext usage at JaxbXmlFormatMapper.java:266-282). This IllegalArgumentException wraps a JAXBException thrown while unmarshalling the stored column XML into the attribute type. The wrapped JAXBException (UnmarshalException, validation error) carries the actual reason.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jaxb/JaxbXmlFormatMapper.java:272
//noinspection unchecked
final T array = (T) Array.newInstance( valueClass, length );
int i = 0;
for ( Object element : elements ) {
final Object value = valueTransformer.fromJAXBElement( element, unmarshaller );
Array.set( array, i, value );
i++;
}
return array;
}
}
else {
final JAXBContext context = JAXBContext.newInstance( javaType.getJavaTypeClass() );
//noinspection unchecked
return (T) context.createUnmarshaller().unmarshal( new StringReader( charSequence.toString() ) );
}
}
catch (JAXBException 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;
}
try {
final StringWriter stringWriter = new StringWriter();
final StringBuilderSqlAppender appender = new StringBuilderSqlAppender();
if ( Map.class.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
final JAXBContext context;
final Class<?> keyClass;
final Class<?> valueClass;
final Map<?, ?> map = (Map<?, ?>) value;
if ( javaType.getJavaType() instanceof ParameterizedType parameterizedType ) {
final Type[] typeArguments = parameterizedType.getActualTypeArguments();View on GitHub (pinned to fad1729dce)
Solutions
- Annotate the attribute type for JAXB: @XmlRootElement, @XmlAccessorType(XmlAccessType.FIELD), @XmlElement names matching the stored XML.
- Add a public no-arg constructor and register @XmlJavaTypeAdapters for java.time and other non-JAXB types.
- Fix or migrate stored XML rows whose structure does not match the class.
- If the type is Jackson-oriented, force the Jackson XML mapper instead (hibernate.type.xml_format_mapper=jackson-xml) so your Jackson annotations apply.
Example fix
// before - no JAXB annotations, unmarshalling fails
public class Config {
public String key; // JAXB maps nothing, stored XML mismatches
}
// after - JAXB-mapped type
@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.FIELD)
public class Config {
@XmlElement(name = "key")
public String key;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate stored XML against the JAXB context before it becomes an entity
static void assertUnmarshallable(String xml, Class<?> type) {
try {
JAXBContext.newInstance( type ).createUnmarshaller().unmarshal( new StringReader( xml ) );
} catch ( JAXBException e ) {
throw new IllegalArgumentException( "Stored XML will fail on load: " + e.getMessage(), e );
}
} Try / catch
try {
return session.find( Doc.class, id );
} catch ( IllegalArgumentException e ) {
if ( e.getCause() instanceof jakarta.xml.bind.JAXBException jaxb ) {
// stored XML <-> annotated class mismatch; check the linked cause
} else throw e;
} Prevention
- Annotate SQLXML types with @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) from day one.
- Provide @XmlJavaTypeAdapter for java.time and other non-JAXB types.
- Decide the mapper deliberately (hibernate.type.xml_format_mapper) so annotations and implementation match.
When it happens
Trigger: Loading an entity whose XML attribute class is not JAXB-mappable (no public no-arg constructor, fields without @XmlElement mapping, java.time fields without an XmlAdapter); stored XML whose element structure does not match the annotated class; malformed XML in the column.
Common situations: Annotating a type with @JdbcTypeCode(SqlTypes.SQLXML) assuming Jackson-style behavior while the classpath resolves the JAXB mapper; keeping Jackson annotations on a class now serialized by JAXB; schema drift between stored XML and the annotated class after refactors; missing jakarta.xml.bind annotations entirely.
Related errors
- Could not deserialize string to java type: {}
- Could not serialize object of java type: {}
- Could not serialize object of java type: {}
- Could not locate root element
- Unable to perform unmarshalling at line number {} and column
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/7330b6b6dabb90f0.
Report an issue: GitHub.