hibernate/hibernate-orm · error · IllegalArgumentException

Could not deserialize string to java type: {}

Error message

Could not deserialize string to java type: {}

What it means

JsonBJsonFormatMapper is the JSON FormatMapper Hibernate picks for SqlTypes.JSON attributes when a jakarta.json.bind (JSON-B) implementation such as Yasson is available. fromString (JsonBJsonFormatMapper.java:35-42) wraps a JsonbException thrown when Jsonb.fromJson cannot parse the stored column text into the attribute's Java type. The Yasson/JSON-B reason (unknown property, no usable constructor, date format) is in the cause.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jakartajson/JsonBJsonFormatMapper.java:40

	public static final String SHORT_NAME = "jsonb";

	private final Jsonb jsonb;

	public JsonBJsonFormatMapper() {
		this( JsonbBuilder.create() );
	}

	public JsonBJsonFormatMapper(Jsonb jsonb) {
		this.jsonb = jsonb;
	}

	@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

  1. Give the attribute type a public no-arg constructor (or a static @JsonbCreator factory) so JSON-B can build it.
  2. Annotate the type with @JsonbProperty/@JsonbDateFormat/@JsonbTransient to align property names and formats with the stored JSON.
  3. Clean or migrate rows whose JSON does not match the current type schema.
  4. If the type is hard to adapt, switch to the Jackson mapper (add jackson-databind to the classpath or set hibernate.type.json_format_mapper=jackson), which ignores unknown properties more leniently.
  5. Provide a preconfigured Jsonb through new JsonBJsonFormatMapper(jsonb) via the hibernate.type.json_format_mapper setting for full control.

Example fix

// before - no no-arg constructor, JSON-B cannot instantiate it
public class Payload {
    public Payload(String a, String b) { ... }
}

// after - JSON-B-friendly type
public class Payload {
    public Payload() {}
    public Payload(String a, String b) { ... }
    @JsonbProperty("a") public String a;
    @JsonbProperty("b") public String b;
}
Defensive patterns

Strategy: validation

Validate before calling

// Round-trip check types destined for JSON columns when using JSON-B
static void assertJsonbReadable(String json, Class<?> type) {
    try ( Jsonb jsonb = JsonbBuilder.create() ) {
        jsonb.fromJson( json, type );
    } catch ( JsonbException e ) {
        throw new IllegalArgumentException( "Data will fail on load: " + e.getMessage(), e );
    }
}

Try / catch

try {
    return session.find( Doc.class, id );
} catch ( IllegalArgumentException e ) {
    if ( e.getCause() instanceof jakarta.json.bind.JsonbException je ) {
        // schema mismatch between stored JSON and the attribute type
    } else throw e;
}

Prevention

When it happens

Trigger: Loading an entity with a JSON attribute whose target type has no public no-arg constructor and no @JsonbCreator; stored JSON containing properties absent from the Java type (Yasson fails on unmapped fields); @JsonbDateFormat mismatch for date fields; column text that is not valid JSON.

Common situations: Switching the classpath from Jackson to JSON-B (or vice versa) and hitting JSON-B's stricter defaults; adding fields to the Java type while old rows contain extra/missing properties; other applications writing the column with a different schema; setting hibernate.type.json_format_mapper=jsonb explicitly.

Related errors


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