{"record":{"id":"3f9f0ef9028d8561","repo":"hibernate/hibernate-orm","slug":"could-not-deserialize-string-to-java-type-3f9f0e","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/jakartajson/JsonBJsonFormatMapper.java","lineNumber":40,"sourceCode":"\tpublic static final String SHORT_NAME = \"jsonb\";\n\n\tprivate final Jsonb jsonb;\n\n\tpublic JsonBJsonFormatMapper() {\n\t\tthis( JsonbBuilder.create() );\n\t}\n\n\tpublic JsonBJsonFormatMapper(Jsonb jsonb) {\n\t\tthis.jsonb = jsonb;\n\t}\n\n\t@Override\n\tpublic <T> T fromString(CharSequence charSequence, Type type) {\n\t\ttry {\n\t\t\treturn jsonb.fromJson( charSequence.toString(), type );\n\t\t}\n\t\tcatch (JsonbException 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 jsonb.toJson( value, type );\n\t\t}\n\t\tcatch (JsonbException e) {\n\t\t\tthrow new IllegalArgumentException( \"Could not serialize object of java type: \" + type, e );\n\t\t}\n\t}\n}\n","sourceCodeStart":22,"sourceCodeEnd":54,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/format/jakartajson/JsonBJsonFormatMapper.java#L22-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Give the attribute type a public no-arg constructor (or a static @JsonbCreator factory) so JSON-B can build it.","Annotate the type with @JsonbProperty/@JsonbDateFormat/@JsonbTransient to align property names and formats with the stored JSON.","Clean or migrate rows whose JSON does not match the current type schema.","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.","Provide a preconfigured Jsonb through new JsonBJsonFormatMapper(jsonb) via the hibernate.type.json_format_mapper setting for full control."],"exampleFix":"// before - no no-arg constructor, JSON-B cannot instantiate it\npublic class Payload {\n    public Payload(String a, String b) { ... }\n}\n\n// after - JSON-B-friendly type\npublic class Payload {\n    public Payload() {}\n    public Payload(String a, String b) { ... }\n    @JsonbProperty(\"a\") public String a;\n    @JsonbProperty(\"b\") public String b;\n}","handlingStrategy":"validation","validationCode":"// Round-trip check types destined for JSON columns when using JSON-B\nstatic void assertJsonbReadable(String json, Class<?> type) {\n    try ( Jsonb jsonb = JsonbBuilder.create() ) {\n        jsonb.fromJson( json, type );\n    } catch ( JsonbException e ) {\n        throw new IllegalArgumentException( \"Data will fail on load: \" + e.getMessage(), e );\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.find( Doc.class, id );\n} catch ( IllegalArgumentException e ) {\n    if ( e.getCause() instanceof jakarta.json.bind.JsonbException je ) {\n        // schema mismatch between stored JSON and the attribute type\n    } else throw e;\n}","preventionTips":["Give every JSON-B mapped type a public no-arg constructor or @JsonbCreator.","Keep stored JSON and the Java type in lockstep - add-and-migrate fields in one release.","Add jackson-databind (or set hibernate.type.json_format_mapper) if you prefer lenient unknown-field handling.","Integration-test loads against realistic column payloads, not just freshly written ones."],"tags":["hibernate","json","json-b","yasson","orm","deserialization"],"backgroundTag":"json-deserialization-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}