{"record":{"id":"5d7b017e6b937c69","repo":"hibernate/hibernate-orm","slug":"could-not-deserialize-string-to-java-type","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/Jackson3JsonFormatMapper.java","lineNumber":79,"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 jsonMapper.readValue( charSequence.toString(), jsonMapper.constructType( type ) );\n\t\t}\n\t\tcatch (JacksonException 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 jsonMapper.writerFor( jsonMapper.constructType( type ) ).writeValueAsString( value );\n\t\t}\n\t\tcatch (JacksonException e) {\n\t\t\tthrow new IllegalArgumentException( \"Could not serialize object of java type: \" + type, e );\n\t\t}\n\t}\n}\n","sourceCodeStart":61,"sourceCodeEnd":93,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/format/jackson/Jackson3JsonFormatMapper.java#L61-L93","documentation":"Jackson3JsonFormatMapper is Hibernate's Jackson 3 (tools.jackson) based JSON FormatMapper, used for @JdbcTypeCode(SqlTypes.JSON) attributes. fromString() wraps any JacksonException thrown by jsonMapper.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 or querying an entity with a JSON-mapped attribute where: the column holds malformed JSON; the JSON shape does not match the type (unknown fields under strict settings, number-vs-string mismatches); the target type lacks a usable constructor/creator; or a required module/serializer for a field type is not registered on the mapper Hibernate uses.","commonSituations":"Schema drift between the JSON producer and the Hibernate mapping (renamed/added fields); another application writing the column; migrating an app from Jackson 2 to Jackson 3 where module registration and defaults differ; switching the JSON column representation between dialects.","solutions":["Unwrap and read the cause (IllegalArgumentException.getCause()) — the JacksonException states the exact problem and input location","Align the mapped Java type with the stored JSON: adjust fields, or tolerate drift with @JsonIgnoreProperties(ignoreUnknown = true) / @JsonIgnore on the DTO","Build a JsonMapper with the modules/features you need and inject it: new Jackson3JsonFormatMapper(mapper) via the hibernate.type.json_format_mapper setting","Repair malformed column data identified by the exception"],"exampleFix":"// before: default mapper, load fails on JSON/entity mismatch\nMap<String, Object> props = session.find(MyEntity.class, id).getProps();\n// after: supply a tolerant, preconfigured mapper\nJsonMapper mapper = JsonMapper.builder()\n        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)\n        .build();\nproperties.put(AvailableSettings.JSON_FORMAT_MAPPER, () -> new Jackson3JsonFormatMapper(mapper));","handlingStrategy":"try-catch","validationCode":"// sanity-check the column shape against the mapped type before/while loading\nstatic <T> void validateJsonMatches(String json, Class<T> type) {\n    try {\n        tools.jackson.databind.json.JsonMapper mapper = tools.jackson.databind.json.JsonMapper.builder().build();\n        mapper.readValue(json, mapper.constructType(type));\n    } catch (tools.jackson.core.JacksonException e) {\n        throw new IllegalArgumentException(\"Column JSON does not match \" + type + \": \" + e.getMessage(), 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        Throwable cause = ex.getCause(); // the real JacksonException with location details\n        throw new DataQualityException(\"JSON column incompatible with mapping: \" + cause.getMessage(), ex);\n    }\n    throw ex;\n}","preventionTips":["Always inspect getCause() - the wrapped JacksonException states the exact field and offset","Annotate JSON DTOs with @JsonIgnoreProperties(ignoreUnknown = true) to survive schema drift","Inject a preconfigured JsonMapper via hibernate.type.json_format_mapper instead of relying on defaults"],"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"}