{"record":{"id":"078d264aa45e9b9c","repo":"hibernate/hibernate-orm","slug":"failed-to-serialize-json-mapping","errorCode":null,"errorMessage":"Failed to serialize JSON mapping","messagePattern":"Failed to serialize JSON mapping","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java","lineNumber":122,"sourceCode":"\t}\n\n\t@Override\n\tpublic Object[] extractJdbcValues(Object rawJdbcValue, WrapperOptions options)\n\t\t\tthrows SQLException {\n\t\tassert embeddableMappingType != null;\n\t\treturn JsonHelper.deserialize( embeddableMappingType,\n\t\t\t\tnew StringJsonDocumentReader( (String) rawJdbcValue ), false, options );\n\t}\n\n\tprotected <X> String toString(X value, JavaType<X> javaType, WrapperOptions options) {\n\t\tif ( embeddableMappingType != null ) {\n\t\t\ttry {\n\t\t\t\tfinal var writer = new StringJsonDocumentWriter();\n\t\t\t\tJsonGeneratingVisitor.INSTANCE.visit( embeddableMappingType, value, options, writer );\n\t\t\t\treturn writer.getJson();\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tthrow new RuntimeException(\"Failed to serialize JSON mapping\", e );\n\t\t\t}\n\t\t}\n\t\treturn options.getJsonFormatMapper().toString( value, javaType, options );\n\t}\n\n\t@Override\n\tpublic <X> ValueBinder<X> getBinder(JavaType<X> javaType) {\n\t\treturn new BasicBinder<>( javaType, this ) {\n\t\t\t@Override\n\t\t\tprotected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)\n\t\t\t\t\tthrows SQLException {\n\t\t\t\tst.setString( index, JsonJdbcType.this.toString( value, getJavaType(), options ) );\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tprotected void doBind(CallableStatement st, X value, String name, WrapperOptions options)\n\t\t\t\t\tthrows SQLException {\n\t\t\t\tst.setString( name, JsonJdbcType.this.toString( value, getJavaType(), options ) );","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java#L104-L140","documentation":"JsonJdbcType.toString() serializes an aggregate (JSON)-mapped embeddable through JsonGeneratingVisitor; any IOException from the writer is wrapped in RuntimeException('Failed to serialize JSON mapping'). Because the writer is string-based, real I/O failure is unlikely - the wrapped cause usually hides a deeper serialization problem such as an attribute type the visitor cannot render. Always inspect the cause chain.","triggerScenarios":"Flushing or querying an entity with a json aggregate embeddable whose attribute values cannot be rendered by the visitor (exotic Java types without a usable JdbcLiteralFormatter/JdbcType), or string-conversion paths (e.g., literal rendering) hitting the same visitor.","commonSituations":"Custom or rarely used attribute types inside an @Embeddable mapped with @JdbcTypeCode(SqlTypes.JSON)/struct; mappings that work for normal columns but were never exercised through the JSON aggregate path; format-mapper configuration changes.","solutions":["Read the cause (and its cause) - the real failing attribute/type is named there, not in the outer message.","Keep aggregate embeddable attributes to basic types or nested aggregates; add an AttributeConverter for exotic types so the visitor writes a basic value.","For complex values, map that attribute itself with a custom JsonFormatMapper-friendly type instead of relying on the visitor."],"exampleFix":"// before: exotic attribute inside the JSON embeddable breaks the visitor\n@Embeddable public class Config {\n    UUID tenantId; // renders fine\n    MyCustomType custom; // visitor cannot serialize -> RuntimeException on flush\n}\n\n// after: convert the exotic attribute to a supported basic value\n@Embeddable public class Config {\n    UUID tenantId;\n    @Convert(converter = MyCustomTypeToStringConverter.class)\n    String custom;\n}","handlingStrategy":"try-catch","validationCode":"// Exercise serialization at startup so failures surface early\nsessionFactory.inTransaction(s -> {\n    Product p = new Product();\n    p.setAttrs(defaultAttrs);\n    s.persist(p); // flush runs the JSON visitor now, not at 3am\n    s.remove(p);\n});","typeGuard":null,"tryCatchPattern":"try {\n    session.persist(entity);\n    session.flush();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().equals(\"Failed to serialize JSON mapping\")) {\n        Throwable cause = e.getCause(); // the real attribute/type failure is here\n        // log cause, fix or convert the offending embeddable attribute\n    } else {\n        throw e;\n    }\n}","preventionTips":["Keep aggregate embeddables to basic types and nested aggregates; convert exotic types with @Convert","Persist-and-flush a sample of every aggregate mapping in a startup/CI check","Always unwrap the cause chain of this wrapper before debugging"],"tags":["hibernate","json","serialization","aggregate-mapping","embeddable"],"backgroundTag":"json-serialization-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}