{"record":{"id":"0104c6f956d9d4d0","repo":"hibernate/hibernate-orm","slug":"unsupported-jdbctype-nested-in-struct","errorCode":null,"errorMessage":"Unsupported JdbcType nested in struct: {}","messagePattern":"Unsupported JdbcType nested in struct: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/type/AbstractPostgreSQLStructJdbcType.java","lineNumber":1286,"sourceCode":"\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tappender.append( '}' );\n\t\t\t\t\t\tappender.quoteEnd();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SqlTypes.STRUCT:\n\t\t\t\tif ( subValue != null ) {\n\t\t\t\t\tfinal var structJdbcType = (AbstractPostgreSQLStructJdbcType) jdbcMapping.getJdbcType();\n\t\t\t\t\tappender.quoteStart();\n\t\t\t\t\tstructJdbcType.serializeJdbcValuesTo( appender, options, (Object[]) subValue, '(' );\n\t\t\t\t\tappender.append( ')' );\n\t\t\t\t\tappender.quoteEnd();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new UnsupportedOperationException( \"Unsupported JdbcType nested in struct: \" + jdbcMapping.getJdbcType() );\n\t\t}\n\t}\n\n\tprivate StructAttributeValues getAttributeValues(\n\t\t\tEmbeddableMappingType embeddableMappingType,\n\t\t\tint[] orderMapping,\n\t\t\tObject[] rawJdbcValues,\n\t\t\tWrapperOptions options) throws SQLException {\n\t\tfinal int numberOfAttributeMappings = embeddableMappingType.getNumberOfAttributeMappings();\n\t\tfinal int size = numberOfAttributeMappings + ( embeddableMappingType.isPolymorphic() ? 1 : 0 );\n\t\tfinal StructAttributeValues attributeValues = new StructAttributeValues(\n\t\t\t\tnumberOfAttributeMappings,\n\t\t\t\torderMapping != null ?\n\t\t\t\t\t\tnull :\n\t\t\t\t\t\trawJdbcValues\n\t\t);\n\t\tint jdbcIndex = 0;\n\t\tfor ( int i = 0; i < size; i++ ) {","sourceCodeStart":1268,"sourceCodeEnd":1304,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/type/AbstractPostgreSQLStructJdbcType.java#L1268-L1304","documentation":"When Hibernate serializes the attributes of a PostgreSQL composite/struct into the ROW(...) literal used for binding (AbstractPostgreSQLStructJdbcType.serializeJdbcValuesTo), it switches on each attribute's SQL type class. Only types handled by explicit cases (strings, numerics, booleans, nested STRUCTs, arrays, etc.) can be written; anything else falls through to the default branch and throws UnsupportedOperationException naming the unsupported JdbcType. The error means: one attribute of your @Struct mapping uses a JDBC type Hibernate cannot render inside a PostgreSQL struct literal.","triggerScenarios":"An embeddable mapped with @Struct / SqlTypes.STRUCT on PostgreSQL containing an attribute whose JdbcType is outside the serializer's switch - typical culprits: UUID, JSON/JSONB, java.time types with bespoke JdbcTypes, custom enum JdbcTypes, BINARY/VARBINARY, INTERVAL. The exception fires on INSERT/UPDATE/flush, i.e. whenever the struct literal must be built and sent.","commonSituations":"Adopting PostgreSQL composite types (@Struct) and reusing an existing embeddable that contains a UUID or JSON attribute; mapping a domain object designed for embedded columns directly as a DB composite; upgrading Hibernate and having previously-tolerated attribute types now hit the default branch.","solutions":["Change the offending attribute to a type the serializer supports (String, Integer, Long, BigDecimal, Boolean, another @Struct embeddable, or an array of those).","Convert the attribute to String via @Converter / @JdbcTypeCode(SqlTypes.VARCHAR) so the struct stores its text representation.","Implement a custom JdbcType extending AbstractPostgreSQLStructJdbcType that overrides the serialization switch to handle your nested type.","Move the exotic value out of the struct into its own column or side table.","Check the Hibernate release notes - the set of nested types supported in struct literals grows across versions, so upgrade may alone fix it."],"exampleFix":"// before\n@Embeddable\n@Struct(name = \"address_type\")\npublic class Address {\n    private String city;        // OK\n    private UUID tenantId;      // throws: Unsupported JdbcType nested in struct\n}\n// after\n@Embeddable\n@Struct(name = \"address_type\")\npublic class Address {\n    private String city;\n    @JdbcTypeCode(SqlTypes.VARCHAR)\n    private String tenantId;    // store UUID as text inside the struct\n}","handlingStrategy":"validation","validationCode":"// At startup, verify every @Struct embeddable attribute maps to a serializer-supported Java type\nstatic void checkStructAttributes(Class<?> embeddable) {\n    Set<Class<?>> ok = Set.of(String.class, Integer.class, Long.class, BigDecimal.class, Boolean.class);\n    for (Field f : embeddable.getDeclaredFields()) {\n        Class<?> t = f.getType();\n        boolean supported = ok.contains(t) || t.isAnnotationPresent(Struct.class) || t.isArray();\n        if (!supported) throw new IllegalStateException(\n            \"@Struct \" + embeddable.getSimpleName() + \".\" + f.getName()\n            + \" of type \" + t + \" is not serializable inside a PostgreSQL struct\");\n    }\n}","typeGuard":null,"tryCatchPattern":"catch (UnsupportedOperationException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported JdbcType nested in struct\")) {\n        // message names the JdbcType; map that attribute as String or implement a custom JdbcType\n        throw new MappingConfigurationException(e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Keep @Struct embeddables to primitives, String, BigDecimal, Boolean, nested structs, and arrays; keep UUID/JSON/temporal values out of them.","Cover struct mappings with a smoke test that inserts and reads one row per embeddable, so unsupported attributes fail in CI, not production.","Review Hibernate release notes when adding new attribute types to existing structs."],"tags":["postgresql","struct","composite-type","jdbc-type","unsupported-type","serialization"],"backgroundTag":"unsupported-jdbc-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}