{"record":{"id":"538e71f2d3b60512","repo":"hibernate/hibernate-orm","slug":"could-not-deserialize-string-to-java-type-538e71","errorCode":null,"errorMessage":"Could not deserialize string to java type: {}","messagePattern":"Could not deserialize string to java type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/format/jackson/JacksonJsonFormatMapper.java","lineNumber":76,"sourceCode":"\t}\n\n\t@Override\n\tpublic boolean supportsSourceType(Class<?> sourceType) {\n\t\treturn JsonParser.class.isAssignableFrom( sourceType );\n\t}\n\n\t@Override\n\tpublic boolean supportsTargetType(Class<?> targetType) {\n\t\treturn JsonGenerator.class.isAssignableFrom( targetType );\n\t}\n\n\t@Override\n\tpublic <T> T fromString(CharSequence charSequence, Type type) {\n\t\ttry {\n\t\t\treturn objectMapper.readValue( charSequence.toString(), objectMapper.constructType( type ) );\n\t\t}\n\t\tcatch (JsonProcessingException e) {\n\t\t\tthrow new IllegalArgumentException( \"Could not deserialize string to java type: \" + type, e );\n\t\t}\n\t}\n\n\t@Override\n\tpublic <T> String toString(T value, Type type) {\n\t\ttry {\n\t\t\treturn objectMapper.writerFor( objectMapper.constructType( type ) ).writeValueAsString( value );\n\t\t}\n\t\tcatch (JsonProcessingException e) {\n\t\t\tthrow new IllegalArgumentException( \"Could not serialize object of java type: \" + type, e );\n\t\t}\n\t}\n}\n","sourceCodeStart":58,"sourceCodeEnd":90,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/format/jackson/JacksonJsonFormatMapper.java#L58-L90","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Unwrap the cause (IllegalArgumentException.getCause()) — the JsonProcessingException pinpoints line/column and reason","For unknown-field drift annotate the mapped type with @JsonIgnoreProperties(ignoreUnknown = true) or disable FAIL_ON_UNKNOWN_PROPERTIES","Register missing modules by supplying a configured ObjectMapper: new JacksonJsonFormatMapper(objectMapper) via hibernate.type.json_format_mapper (e.g. mapper.registerModule(new JavaTimeModule()))","Repair malformed rows identified by the failing primary key"],"exampleFix":"// before: java.time in a JSON column, default mapper\n@JdbcTypeCode(SqlTypes.JSON)\nprivate Instant updatedAt; // 'Could not deserialize string to java type': JavaTimeModule missing\n// after: supply a mapper with the module registered\nObjectMapper om = new ObjectMapper().registerModule(new JavaTimeModule());\nproperties.put(AvailableSettings.JSON_FORMAT_MAPPER, () -> new JacksonJsonFormatMapper(om));","handlingStrategy":"try-catch","validationCode":"static <T> T tryParse(String json, Class<T> type, com.fasterxml.jackson.databind.ObjectMapper mapper) {\n    try {\n        return mapper.readValue(json, type);\n    } catch (com.fasterxml.jackson.core.JsonProcessingException e) {\n        throw new IllegalArgumentException(\"JSON does not match \" + type + \": \" + e.getOriginalMessage(), e);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    MyEntity e = session.find(MyEntity.class, id);\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage() != null && ex.getMessage().startsWith(\"Could not deserialize string to java type\")) {\n        com.fasterxml.jackson.core.JsonProcessingException cause =\n                (com.fasterxml.jackson.core.JsonProcessingException) ex.getCause();\n        // cause.getLocation() gives line/column of the mismatch in the stored JSON\n        throw new DataQualityException(\"JSON column incompatible: \" + cause.getOriginalMessage(), ex);\n    }\n    throw ex;\n}","preventionTips":["Unwrap the cause JsonProcessingException first - it carries the exact location and reason","Annotate mapped types with @JsonIgnoreProperties(ignoreUnknown = true) to tolerate added fields","Register JavaTimeModule and other needed modules on a custom mapper injected via hibernate.type.json_format_mapper"],"tags":["hibernate","json","jackson","deserialization","orm-mapping"],"backgroundTag":"json-deserialization-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}