hibernate/hibernate-orm · error · IllegalArgumentException

Could not serialize object of java type: {}

Error message

Could not serialize object of java type: {}

What it means

JaxbXmlFormatMapper.toString marshals a SqlTypes.SQLXML attribute value to XML using a JAXB Marshaller (JaxbXmlFormatMapper.java:491-499). This IllegalArgumentException wraps a JAXBException thrown while marshalling, meaning JAXB cannot render the current value: missing @XmlRootElement on the class, a property JAXB cannot handle (Map with non-String keys, java.time without adapter), or a class not registered with the JAXBContext.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jaxb/JaxbXmlFormatMapper.java:496

							appender,
							( (BasicPluralJavaType<?>) javaType ).getElementJavaType(),
							collectionElementTagName
					);
					for ( int i = 0; i < length; i++ ) {
						list.add( transformer.toJAXBElement( Array.get( value, i ) ) );
					}
					collectionWrapper = new CollectionWrapper( list );
				}
				createMarshaller( context ).marshal( collectionWrapper, stringWriter );
			}
			else {
				final JAXBContext context = JAXBContext.newInstance( javaType.getJavaTypeClass() );
				createMarshaller( context ).marshal( value, stringWriter );
			}
			return stringWriter.toString();
		}
		catch (JAXBException e) {
			throw new IllegalArgumentException( "Could not serialize object of java type: " + javaType, e );
		}
	}

	@Override
	public <T> void writeToTarget(T value, JavaType<T> javaType, Object target, WrapperOptions options) {
	}

	@Override
	public <T> T readFromSource(JavaType<T> javaType, Object source, WrapperOptions options) {
		return null;
	}

	private JAXBElementTransformer createTransformer(
			StringBuilderSqlAppender appender,
			Class<?> elementClass,
			String tagName,
			Object exampleElement,
			JAXBIntrospector introspector,

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add @XmlRootElement and @XmlAccessorType(XmlAccessType.FIELD) to the attribute type.
  2. Replace unsupported structures: Map with non-String keys becomes a List of entry elements; java.time fields get @XmlJavaTypeAdapter adapters.
  3. Verify a public no-arg constructor exists on every type in the value graph.
  4. If the type is built for Jackson, switch the mapper with hibernate.type.xml_format_mapper=jackson-xml instead of JAXB-annotating it.

Example fix

// before - class lacks @XmlRootElement, marshalling fails
public class Note { public String text; }

// after - JAXB can marshal it as the document root
@XmlRootElement(name = "note")
@XmlAccessorType(XmlAccessType.FIELD)
public class Note { @XmlElement public String text; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm a value marshals before it is flushed
static void assertMarshallable(Object value) {
    try {
        JAXBContext.newInstance( value.getClass() )
                .createMarshaller().marshal( value, new StringWriter() );
    } catch ( JAXBException e ) {
        throw new IllegalStateException( "Value will fail on flush: " + e.getMessage(), e );
    }
}

Try / catch

try {
    tx.commit();
} catch ( IllegalArgumentException e ) {
    if ( e.getCause() instanceof jakarta.xml.bind.JAXBException jaxb ) {
        // usually missing @XmlRootElement or an unhandled property type
    } else throw e;
}

Prevention

When it happens

Trigger: Flushing an entity whose XML attribute class lacks @XmlRootElement; value graphs containing Map with complex keys, unadapted java.time fields, or objects without JAXB mappings; getters that throw during marshalling.

Common situations: Switching the XML mapper implementation under an existing mapping without changing annotations; adding Map or Optional fields to an XML-mapped DTO; refactoring the class so its no-arg constructor or annotations disappear.

Related errors


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