hibernate/hibernate-orm · error · IllegalArgumentException

Could not serialize object of java type: {}

Error message

Could not serialize object of java type: {}

What it means

Serialization half of the Jackson 3 JSON FormatMapper: toString() calls jsonMapper.writerFor(type).writeValueAsString(value) and wraps any JacksonException as IllegalArgumentException('Could not serialize object of java type: <type>') with the cause attached. The mapped Java object could not be rendered to JSON — typically at flush time of a JSON-mapped attribute.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jackson/Jackson3JsonFormatMapper.java:89

	}

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

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

View on GitHub (pinned to fad1729dce)

Solutions

  1. Read the cause JacksonException — it names the offending property and reason
  2. Fix the DTO: expose getters (or use records), break cycles with @JsonIgnore/@JsonManagedReference+@JsonBackReference, initialize or detach lazy proxies before assignment
  3. Inject a preconfigured JsonMapper via new Jackson3JsonFormatMapper(mapper) and hibernate.type.json_format_mapper so needed modules/serializers are registered
  4. As a stopgap, convert the value to a plain serializable DTO before storing it

Example fix

// before: cyclic parent/child stored as JSON
// -> 'Could not serialize object of java type: Parent' (JsonMappingException: cycle)
entity.setTree(parentNodeWithChildrenPointingBack);
// after: break the cycle
public class Node {
    public String name;
    @JsonIgnore
    public Node parent;          // not serialized
    public List<Node> children;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify serializability before assigning/flushing
static boolean isSerializable(Object value, tools.jackson.databind.json.JsonMapper mapper) {
    try {
        mapper.writeValueAsString(value);
        return true;
    } catch (tools.jackson.core.JacksonException e) {
        return false;
    }
}

Try / catch

try {
    session.merge(entity);
    session.flush();
} catch (IllegalArgumentException ex) {
    if (ex.getMessage() != null && ex.getMessage().startsWith("Could not serialize object of java type")) {
        Throwable cause = ex.getCause(); // names the offending property
        throw new MappingConfigurationException("Value not JSON-serializable: " + cause.getMessage(), ex);
    }
    throw ex;
}

Prevention

When it happens

Trigger: Persisting/updating a @JdbcTypeCode(SqlTypes.JSON) attribute whose value Jackson cannot serialize: no serializer for a field type (missing getters, exotic type without module), self-referencing object graph (StackOverflowError-adjacent JsonMappingException), or an uninitialized lazy proxy inside the value.

Common situations: Adding a field of a type the mapper does not handle (no module registered); Jackson 2 → Jackson 3 migration changing the registered module set; lazy-loaded associations embedded in a JSON value detached from the session; cyclic object graphs returned by builders.

Related errors


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