hibernate/hibernate-orm · error · IllegalArgumentException

Could not serialize object of java type: {}

Error message

Could not serialize object of java type: {}

What it means

JacksonOsonFormatMapper.toString serializes a SqlTypes.JSON attribute value to column text using Jackson (JacksonOsonFormatMapper.java:94-101). This IllegalArgumentException wraps a JsonProcessingException raised while objectMapper.writerFor(type).writeValueAsString(value) runs, i.e. Jackson cannot serialize the current attribute value. The concrete Jackson reason (no serializer, direct self-reference, missing module for a java.time type) is in the cause.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jackson/JacksonOsonFormatMapper.java:99

	}

	@Override
	public <T> T fromString(CharSequence charSequence, Type type) {
		try {
			return objectMapper.readValue( charSequence.toString(), objectMapper.constructType( type ) );
		}
		catch (JsonProcessingException e) {
			throw new IllegalArgumentException( "Could not deserialize string to java type: " + type, e );
		}
	}

	@Override
	public <T> String toString(T value, Type type) {
		try {
			return objectMapper.writerFor( objectMapper.constructType( type ) ).writeValueAsString( value );
		}
		catch (JsonProcessingException e) {
			throw new IllegalArgumentException( "Could not serialize object of java type: " + type, e );
		}
	}

}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Read the cause's message to identify the offending property/type of the value being flushed.
  2. Annotate the JSON type for Jackson: @JsonIgnore / @JsonManagedReference+@JsonBackReference for cycles, @JsonSerialize adapters for exotic types.
  3. If a custom ObjectMapper is used, register the needed modules (JavaTimeModule, etc.) before handing it to JacksonOsonFormatMapper.
  4. Restructure the attribute to hold only Jackson-friendly types (strings, numbers, collections, plain DTOs).

Example fix

// before - Instant field but the mapper's ObjectMapper has no JavaTimeModule
public class Event {
    public Instant occurredAt; // writeValueAsString fails on flush
}

// after - register the module on the mapper you pass in
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
settings.put(AvailableSettings.JSON_FORMAT_MAPPER, new JacksonOsonFormatMapper(mapper));
Defensive patterns

Strategy: validation

Validate before calling

// Verify the value serializes with a Jackson mapper before flushing
static void assertSerializable(Object value) {
    try {
        new ObjectMapper().findAndRegisterModules().writeValueAsString( value );
    } catch ( JsonProcessingException e ) {
        throw new IllegalStateException( "Value will fail on flush: " + e.getOriginalMessage(), e );
    }
}

Try / catch

try {
    session.persist( doc );
    tx.commit();
} catch ( IllegalArgumentException e ) {
    if ( e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException jpe ) {
        // identify the offending field from jpe.getOriginalMessage() and fix the value/type
    } else throw e;
}

Prevention

When it happens

Trigger: INSERT/UPDATE flush of an entity whose JSON attribute value contains a type Jackson cannot serialize (e.g. java.time.Instant when JavaTimeModule is not registered); a getter of the value throwing an exception; a directly self-referencing object (JsonMappingException: Direct self-reference leading to cycle); a bidirectional relation inside the JSON attribute without @JsonIgnore/@JsonBackReference.

Common situations: Adding java.time fields or polymorphic fields to a JSON-mapped POJO after the mapping worked; passing a custom ObjectMapper (new JacksonOsonFormatMapper(objectMapper)) that was built without findModules; value objects with only getters that throw for uninitialized state.

Related errors


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