{"record":{"id":"439d06136d5f89a2","repo":"hibernate/hibernate-orm","slug":"could-not-determine-recommended-jdbctype-for","errorCode":null,"errorMessage":"Could not determine recommended JdbcType for `\" + getTypeName() + \"`\"","messagePattern":"Could not determine recommended JdbcType for `\" \\+ getTypeName\\(\\) \\+ \"`\"","errorType":"exception","errorClass":"JdbcTypeRecommendationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EmbeddableAggregateJavaType.java","lineNumber":65,"sourceCode":"\t\t}\n\t\t// When the column is mapped as XML array, the component type must be SQLXML\n\t\tfinal Integer explicitJdbcTypeCode = context.getExplicitJdbcTypeCode();\n\t\tif ( explicitJdbcTypeCode != null && explicitJdbcTypeCode == SqlTypes.XML_ARRAY\n\t\t\t\t// Also prefer XML if the Dialect prefers XML arrays\n\t\t\t\t|| explicitJdbcTypeCode == null && context.getDialect().getPreferredSqlTypeCodeForArray() == SqlTypes.XML_ARRAY ) {\n\t\t\tfinal var descriptor = context.getJdbcType( SqlTypes.SQLXML );\n\t\t\tif ( descriptor != null ) {\n\t\t\t\treturn descriptor;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Otherwise use json by default for now\n\t\t\tfinal var descriptor = context.getJdbcType( SqlTypes.JSON );\n\t\t\tif ( descriptor != null ) {\n\t\t\t\treturn descriptor;\n\t\t\t}\n\t\t}\n\t\tthrow new JdbcTypeRecommendationException(\n\t\t\t\t\"Could not determine recommended JdbcType for `\" + getTypeName() + \"`\"\n\t\t);\n\t}\n\n\t@Override\n\tpublic <X> X unwrap(T value, Class<X> type, WrapperOptions options) {\n\t\tif ( type.isAssignableFrom( getJavaTypeClass() ) ) {\n\t\t\treturn type.cast( value );\n\t\t}\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\t\"Unwrap strategy not known for this Java type: \" + getTypeName()\n\t\t);\n\t}\n\n\t@Override\n\tpublic <X> T wrap(X value, WrapperOptions options) {\n\t\tif ( value == null ) {\n\t\t\treturn null;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EmbeddableAggregateJavaType.java#L47-L83","documentation":"EmbeddableAggregateJavaType backs embeddables stored as one aggregate column (JSON or SQL/XML). getRecommendedJdbcType() looks up the dialect's SQLXML or JSON JdbcType; when the dialect registers neither, no column type can be suggested and bootstrap fails with JdbcTypeRecommendationException naming the embeddable's Java type.","triggerScenarios":"Mapping an @Embedded/@Embeddable aggregate (@JdbcTypeCode(SqlTypes.JSON) or SqlTypes.SQLXML) while running on a dialect with no JSON/SQLXML JdbcType — legacy or community dialects, old H2/HSQLDB/Derby versions, or a custom Dialect that never registers JSON support; also enabling the mapping before the JSON TypeContributor runs.","commonSituations":"Switching databases while keeping JSON-mapped embeddables; test suites running on an embedded database that lacks JSON; upgrading Hibernate where dialect JSON support moved or requires hibernate-community-dialects.","solutions":["Switch to a dialect with native JSON support (PostgreSQL, H2 2.x+, MariaDB 10.5+/MySQL 8, SQL Server) or upgrade the hibernate-community-dialects artifact","Register a JSON JdbcType from a TypeContributor: typeConfiguration.getJdbcTypeRegistry().addDescriptorIfAbsent(jsonJdbcType)","Fall back to SqlTypes.LONG_STRING plus an AttributeConverter that serializes the embeddable manually","Upgrade the database/engine itself to a version with JSON or XML support"],"exampleFix":"// before: aggregate embeddable on a dialect without JSON JDBC type\n@Embeddable class Address { String city; }\n@Entity class Customer {\n    @Embedded @JdbcTypeCode(SqlTypes.JSON)\n    Address address; // boot fails: no JSON/SQLXML descriptor registered\n}\n\n// after: use a JSON-capable dialect\n// spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect\n@Embeddable class Address { String city; }\n@Entity class Customer {\n    @Embedded @JdbcTypeCode(SqlTypes.JSON)\n    Address address;\n}","handlingStrategy":"validation","validationCode":"// fail fast at boot when the dialect cannot host JSON/XML aggregates\norg.hibernate.type.descriptor.java.spi.JdbcTypeRegistry jdbcTypes =\n    typeConfiguration.getJdbcTypeRegistry();\nif (jdbcTypes.getDescriptor(org.hibernate.type.SqlTypes.JSON) == null\n        && jdbcTypes.getDescriptor(org.hibernate.type.SqlTypes.SQLXML) == null) {\n    throw new IllegalStateException(\n        \"Dialect has no JSON/SQLXML JdbcType: cannot map aggregate embeddables\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    metadata.buildSessionFactory();\n} catch (org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException e) {\n    // switch to a JSON-capable dialect or register a JsonJdbcType via TypeContributor, then retry\n}","preventionTips":["Verify the target database has native JSON/XML support before choosing aggregate embeddable mapping","Pin dialect and Hibernate versions together; test on every DB you ship on","Bootstrap smoke tests in CI catch missing dialect JSON support early"],"tags":["hibernate","orm","json","jdbc-type","dialect","bootstrap"],"backgroundTag":"jdbc-type-resolution-failure","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}