hibernate/hibernate-orm · error · IllegalArgumentException

Could not deserialize string to java type: {}

Error message

Could not deserialize string to java type: {}

What it means

JacksonJsonFormatMapper is Hibernate 6's default JSON FormatMapper built on Jackson 2 (com.fasterxml.jackson), used for @JdbcTypeCode(SqlTypes.JSON). fromString() wraps JsonProcessingException from objectMapper.readValue() into IllegalArgumentException('Could not deserialize string to java type: <type>') with the original exception as cause — the JSON column content could not be bound to the mapped Java type.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/jackson/JacksonJsonFormatMapper.java:76

	}

	@Override
	public boolean supportsSourceType(Class<?> sourceType) {
		return JsonParser.class.isAssignableFrom( sourceType );
	}

	@Override
	public boolean supportsTargetType(Class<?> targetType) {
		return JsonGenerator.class.isAssignableFrom( targetType );
	}

	@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. Unwrap the cause (IllegalArgumentException.getCause()) — the JsonProcessingException pinpoints line/column and reason
  2. For unknown-field drift annotate the mapped type with @JsonIgnoreProperties(ignoreUnknown = true) or disable FAIL_ON_UNKNOWN_PROPERTIES
  3. Register missing modules by supplying a configured ObjectMapper: new JacksonJsonFormatMapper(objectMapper) via hibernate.type.json_format_mapper (e.g. mapper.registerModule(new JavaTimeModule()))
  4. Repair malformed rows identified by the failing primary key

Example fix

// before: java.time in a JSON column, default mapper
@JdbcTypeCode(SqlTypes.JSON)
private Instant updatedAt; // 'Could not deserialize string to java type': JavaTimeModule missing
// after: supply a mapper with the module registered
ObjectMapper om = new ObjectMapper().registerModule(new JavaTimeModule());
properties.put(AvailableSettings.JSON_FORMAT_MAPPER, () -> new JacksonJsonFormatMapper(om));
Defensive patterns

Strategy: try-catch

Validate before calling

static <T> T tryParse(String json, Class<T> type, com.fasterxml.jackson.databind.ObjectMapper mapper) {
    try {
        return mapper.readValue(json, type);
    } catch (com.fasterxml.jackson.core.JsonProcessingException e) {
        throw new IllegalArgumentException("JSON does not match " + type + ": " + e.getOriginalMessage(), e);
    }
}

Try / catch

try {
    MyEntity e = session.find(MyEntity.class, id);
} catch (IllegalArgumentException ex) {
    if (ex.getMessage() != null && ex.getMessage().startsWith("Could not deserialize string to java type")) {
        com.fasterxml.jackson.core.JsonProcessingException cause =
                (com.fasterxml.jackson.core.JsonProcessingException) ex.getCause();
        // cause.getLocation() gives line/column of the mismatch in the stored JSON
        throw new DataQualityException("JSON column incompatible: " + cause.getOriginalMessage(), ex);
    }
    throw ex;
}

Prevention

When it happens

Trigger: Loading/querying a JSON-mapped entity when: the column holds malformed JSON; unknown fields exist while FAIL_ON_UNKNOWN_PROPERTIES is enabled (Jackson 2 default); a java.time field is mapped but JavaTimeModule is not registered; the target type lacks a default constructor/creator; values have the wrong JSON type (string where number expected).

Common situations: Schema drift between the JSON writer and the Hibernate mapping; storing java.time Instant/LocalDateTime in JSON without registering jackson-datatype-jsr310 on the mapper Hibernate uses; another service writing the column; property renames after refactors.

Related errors


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