{"record":{"id":"c4ba1aca192d7fcd","repo":"hibernate/hibernate-orm","slug":"could-not-deserialize-string-to-java-type-c4ba1a","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/JacksonOsonFormatMapper.java","lineNumber":89,"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}\n","sourceCodeStart":71,"sourceCodeEnd":104,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/format/jackson/JacksonOsonFormatMapper.java#L71-L104","documentation":"JacksonOsonFormatMapper is the JSON FormatMapper Hibernate uses for @JdbcTypeCode(SqlTypes.JSON) attributes on Oracle (Jackson ObjectMapper plus the Oracle OsonModule, see JacksonOsonFormatMapper.java:55-59). This IllegalArgumentException wraps a Jackson JsonProcessingException thrown when ObjectMapper.readValue fails to parse the stored column text into the attribute's Java type. The original Jackson message (malformed JSON, unknown field, no deserializer, wrong shape) is in the cause.","triggerScenarios":"Loading an entity whose SqlTypes.JSON attribute column contains malformed JSON or JSON whose shape does not match the attribute type (e.g. a JSON array stored for a POJO field); the attribute type not being Jackson-deserializable (no default constructor, missing @JsonCreator, java.time fields without JavaTimeModule registered on the ObjectMapper passed to new JacksonOsonFormatMapper(ObjectMapper)); hand-edited or externally migrated column data.","commonSituations":"Changing the entity field type (e.g. Map to POJO) without migrating the JSON already stored in the Oracle column; JSON written by another application or an older Hibernate version; supplying a custom ObjectMapper that lacks the modules the previous mapper had; enabling the mapper via hibernate.type.json_format_mapper=jackson-oson against dirty data.","solutions":["Inspect the failing row's JSON column and fix the data so it matches the attribute's Java type (shape, field names, types).","Align the entity attribute type with what is actually stored (e.g. switch List<Integer> vs Pojo), or make the type tolerant with @JsonIgnoreProperties(ignoreProperties = true) and a default constructor/@JsonCreator.","If you constructed JacksonOsonFormatMapper(ObjectMapper) yourself, register the modules the type needs (e.g. JavaTimeModule via findModules or registerModule).","If you need full control, plug a custom FormatMapper through the hibernate.type.json_format_mapper setting instead of relying on the default.","Run a data-repair migration for rows whose JSON predates a type change."],"exampleFix":"// before - column holds [1,2,3] but the attribute expects an object\n@Entity\nclass Doc {\n    @JdbcTypeCode(SqlTypes.JSON)\n    MyPojo payload; // readValue fails -> IllegalArgumentException\n}\n\n// after - attribute type matches the stored JSON shape\n@Entity\nclass Doc {\n    @JdbcTypeCode(SqlTypes.JSON)\n    List<Integer> payload; // matches the stored array\n}","handlingStrategy":"try-catch","validationCode":"// When importing/migrating data into a JSON column, verify it parses\n// against the attribute type before inserting:\ntry {\n    ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();\n    MyPojo check = mapper.readValue( candidateJson, MyPojo.class );\n} catch ( JsonProcessingException e ) {\n    throw new IllegalArgumentException( \"Row will fail on load: \" + e.getOriginalMessage(), e );\n}","typeGuard":null,"tryCatchPattern":"try {\n    Doc doc = session.find( Doc.class, id );\n} catch ( IllegalArgumentException e ) {\n    if ( e.getCause() instanceof com.fasterxml.jackson.core.JsonProcessingException jpe ) {\n        // column data <-> attribute type mismatch: log row id and jpe.getOriginalMessage()\n    } else throw e;\n}","preventionTips":["Round-trip test every JSON-mapped attribute type (serialize + deserialize) in unit tests before shipping mapping changes.","Never hand-edit JSON columns; run migrations through the entity or a validated import path.","When swapping the mapper (jackson vs jsonb vs jackson-oson), re-run integration tests against existing data.","Keep the attribute type tolerant: @JsonIgnoreProperties(ignoreProperties = true) and an explicit default constructor."],"tags":["hibernate","json","jackson","oracle","oson","orm","deserialization"],"backgroundTag":"json-deserialization-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}