{"record":{"id":"67b37af8d57acbe5","repo":"hibernate/hibernate-orm","slug":"tried-to-resolve-the-jdbctype-s-as-aggregatejdb","errorCode":null,"errorMessage":"Tried to resolve the JdbcType [%s] as AggregateJdbcType but it does not implement that interface!","messagePattern":"Tried to resolve the JdbcType \\[(.+?)\\] as AggregateJdbcType but it does not implement that interface!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/JdbcTypeRegistry.java","lineNumber":185,"sourceCode":"\t\t}\n\t\treturn resolveAggregateDescriptor( jdbcTypeCode, typeName, embeddableMappingType, context, registrationKey );\n\t}\n\n\tprivate AggregateJdbcType resolveAggregateDescriptor(\n\t\t\tint jdbcTypeCode,\n\t\t\tString typeName,\n\t\t\tEmbeddableMappingType embeddableMappingType,\n\t\t\tRuntimeModelCreationContext context,\n\t\t\tString registrationKey) {\n\t\tfinal var descriptor = getDescriptor( jdbcTypeCode );\n\t\tif ( descriptor instanceof AggregateJdbcType aggregateJdbcType ) {\n\t\t\tfinal AggregateJdbcType resolvedJdbcType =\n\t\t\t\t\taggregateJdbcType.resolveAggregateJdbcType( embeddableMappingType, typeName, context );\n\t\t\tcacheAggregateJdbcType( registrationKey, resolvedJdbcType );\n\t\t\treturn resolvedJdbcType;\n\t\t}\n\t\telse {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\"Tried to resolve the JdbcType [%s] as AggregateJdbcType but it does not implement that interface!\",\n\t\t\t\t\t\t\tdescriptor.getClass().getName()\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate void cacheAggregateJdbcType(String registrationKey, AggregateJdbcType resolvedJdbcType) {\n\t\tif ( registrationKey != null ) {\n\t\t\taggregateDescriptorMap.put( registrationKey, resolvedJdbcType );\n\t\t\tif ( resolvedJdbcType instanceof SqlTypedJdbcType sqlTypedJdbcType ) {\n\t\t\t\tsqlTypedDescriptorMap.put(\n\t\t\t\t\t\tsqlTypedJdbcType.getSqlTypeName().toLowerCase( Locale.ROOT ),\n\t\t\t\t\t\tsqlTypedJdbcType\n\t\t\t\t);\n\t\t\t}\n\t\t}","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/JdbcTypeRegistry.java#L167-L203","documentation":"During boot, JdbcTypeRegistry.resolveAggregateDescriptor looks up the JdbcType registered for the requested JDBC type code and requires it to implement AggregateJdbcType when an embeddable is mapped onto an aggregate column. If a non-aggregate descriptor is registered under that code, aggregate mapping creation fails with this IllegalArgumentException naming the offending class.","triggerScenarios":"Mapping an embeddable as an aggregate while the effective JdbcType for the column is not aggregate-capable: @JdbcType on the embeddable pointing at a plain JdbcType, @JdbcTypeCode with a code whose registered descriptor is not aggregate (e.g. SqlTypes.VARCHAR on an embeddable), or a custom JdbcTypeRegistrar/TypeContributor overriding SqlTypes.STRUCT/JSON/SQLXML codes with a non-aggregate implementation.","commonSituations":"Custom type contributions added by a library or dialect integration; copy-pasted @JdbcType annotations from non-aggregate mappings; conflicting type contributors on the classpath after dependency upgrades.","solutions":["Use the intended aggregate annotation: @Struct, or @JdbcTypeCode(SqlTypes.STRUCT | SqlTypes.JSON | SqlTypes.SQLXML) on the embeddable.","If a custom JdbcType must back the aggregate, make it implement AggregateJdbcType (extend or delegate to XmlJdbcType/JsonJdbcType/StructJdbcType).","Find and remove/fix the JdbcTypeRegistrar or TypeContributor that overrode the code, e.g. by enabling Hibernate's type logging at startup."],"exampleFix":"// before: non-aggregate type forced onto an aggregate mapping\n@Embeddable\n@JdbcType(VarcharJdbcType.class)   // -> Tried to resolve the JdbcType ... as AggregateJdbcType\npublic class Details { ... }\n// after\n@Embeddable\n@JdbcTypeCode(SqlTypes.JSON)       // registered descriptor implements AggregateJdbcType\npublic class Details { ... }","handlingStrategy":"validation","validationCode":"static void assertAggregateCapable(JdbcType jdbcType) {\n    if (!(jdbcType instanceof AggregateJdbcType)) {\n        throw new IllegalStateException(jdbcType.getClass().getName()\n            + \" must implement AggregateJdbcType to back an aggregate mapping\");\n    }\n}","typeGuard":"static boolean isAggregateJdbcType(JdbcType t) {\n    return t instanceof AggregateJdbcType;\n}","tryCatchPattern":"try {\n    sessionFactory = new Configuration().addAnnotatedClass(Person.class)\n        .buildSessionFactory();\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage() != null && ex.getMessage().contains(\"as AggregateJdbcType\")) {\n        throw new ConfigurationException(\n            \"An embeddable aggregate resolves to a non-aggregate JdbcType; \"\n            + \"check @JdbcType/@JdbcTypeCode and custom JdbcTypeRegistrars\", ex);\n    }\n    throw ex;\n}","preventionTips":["Use @Struct or @JdbcTypeCode(SqlTypes.STRUCT/JSON/SQLXML) on aggregate-mapped embeddables.","Make custom JdbcTypes for aggregate columns implement AggregateJdbcType by extending XmlJdbcType/JsonJdbcType/StructJdbcType.","Audit classpath type contributors (JdbcTypeRegistrar, TypeContributor) after dependency upgrades."],"tags":["hibernate","jdbc-type","aggregate-mapping","boot","type-contributor"],"backgroundTag":"jdbc-type-registration-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}