hibernate/hibernate-orm · error · IllegalArgumentException
Could not serialize object of java type: {}
Error message
Could not serialize object of java type: {} What it means
JsonBJsonFormatMapper.toString serializes a SqlTypes.JSON attribute value to column text using jakarta.json.bind Jsonb.toJson (JsonBJsonFormatMapper.java:44-51). This IllegalArgumentException wraps a JsonbException thrown while serializing the current value, i.e. JSON-B cannot render the attribute's runtime object. The Yasson message in the cause names the property or type it failed on.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jakartajson/JsonBJsonFormatMapper.java:50
}
@Override
public <T> T fromString(CharSequence charSequence, Type type) {
try {
return jsonb.fromJson( charSequence.toString(), type );
}
catch (JsonbException e) {
throw new IllegalArgumentException( "Could not deserialize string to java type: " + type, e );
}
}
@Override
public <T> String toString(T value, Type type) {
try {
return jsonb.toJson( value, type );
}
catch (JsonbException e) {
throw new IllegalArgumentException( "Could not serialize object of java type: " + type, e );
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Read the cause message to find the offending property/type.
- Annotate the value type for JSON-B (@JsonbProperty, @JsonbDateFormat, @JsonbTransient) or convert java.time fields to strings.
- Configure a Jsonb with the needed adapters/serializers and pass it via new JsonBJsonFormatMapper(jsonb) through the hibernate.type.json_format_mapper setting.
- Keep the attribute type a plain DTO graph so any JSON-B runtime can serialize it.
Example fix
// before - OffsetDateTime field fails under default Yasson serialization
public class Audit {
public OffsetDateTime changedAt;
}
// after - explicit format makes it serializable
public class Audit {
@JsonbDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
public OffsetDateTime changedAt;
} Defensive patterns
Strategy: validation
Validate before calling
// Confirm JSON-B can serialize a value before depending on the flush
try ( Jsonb jsonb = JsonbBuilder.create() ) {
jsonb.toJson( value ); // throws JsonbException early if not serializable
} Try / catch
try {
tx.commit();
} catch ( IllegalArgumentException e ) {
if ( e.getCause() instanceof jakarta.json.bind.JsonbException je ) {
// fix the value type (annotations/adapters) per je.getMessage()
} else throw e;
} Prevention
- Annotate java.time fields with @JsonbDateFormat; add JsonbAdapter for exotic types.
- Keep the attribute type to plain DTOs; avoid polymorphic fields unless annotated for JSON-B.
- Prefer configuring a custom Jsonb instance via the mapper setting over fighting defaults.
When it happens
Trigger: Flushing an entity whose JSON attribute holds a value JSON-B cannot serialize (e.g. java.time types without a format JSON-B supports, polymorphic types without @JsonbTypeInfo, custom classes without readable properties); getters of the value throwing exceptions during serialization.
Common situations: Moving an application from a Jackson-based mapper to JSON-B where serialization defaults differ; adding java.time or generic Object fields to a JSON-mapped DTO; custom Jsonb instances configured with strict property visibility.
Related errors
- Could not deserialize string to java type: {}
- Could not serialize object of java type: {}
- Could not determine recommended JdbcType for `" + getTypeNam
- Unwrap strategy not known for this Java type: " + getTypeNam
- Wrap strategy not known for this Java type: " + getTypeName(
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/4155e31727a4e36e.
Report an issue: GitHub.