{"record":{"id":"647d88d6735182bc","repo":"hibernate/hibernate-orm","slug":"unable-to-determine-sql-type-name-for-column-s-647d88","errorCode":null,"errorMessage":"Unable to determine SQL type name for column '%s' of table '%s'","messagePattern":"Unable to determine SQL type name for column '(.+?)' of table '(.+?)'","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/mapping/Column.java","lineNumber":561,"sourceCode":"\n\tpublic boolean isSqlTypeLob(Metadata mapping) {\n\t\tfinal var database = mapping.getDatabase();\n\t\tfinal var ddlTypeRegistry = database.getTypeConfiguration().getDdlTypeRegistry();\n\t\tfinal var dialect = database.getDialect();\n\t\tif ( sqlTypeLob == null ) {\n\t\t\ttry {\n\t\t\t\tfinal int typeCode = getSqlTypeCode( mapping );\n\t\t\t\tfinal var ddlType = ddlTypeRegistry.getDescriptor( typeCode );\n\t\t\t\tsqlTypeLob =\n\t\t\t\t\t\tddlType == null\n\t\t\t\t\t\t\t\t? JdbcType.isLob( typeCode )\n\t\t\t\t\t\t\t\t: ddlType.isLob( getColumnSize( dialect, mapping ) );\n\t\t\t}\n\t\t\tcatch ( MappingException cause ) {\n\t\t\t\tthrow cause;\n\t\t\t}\n\t\t\tcatch ( Exception cause ) {\n\t\t\t\tthrow new MappingException(\n\t\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\t\"Unable to determine SQL type name for column '%s' of table '%s'\",\n\t\t\t\t\t\t\t\tgetName(),\n\t\t\t\t\t\t\t\tgetValue().getTable().getName()\n\t\t\t\t\t\t),\n\t\t\t\t\t\tcause\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn sqlTypeLob;\n\t}\n\n\tpublic void setUnique(boolean unique) {\n\t\tthis.unique = unique;\n\t}\n\n\tpublic String getUniqueKeyName() {","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/mapping/Column.java#L543-L579","documentation":"Thrown from Column#isLob() while Hibernate resolves a column's SQL type during metadata building or DDL generation. The calls getSqlTypeCode(mapping) plus the DdlTypeRegistry descriptor lookup raised an unexpected exception, which Hibernate wraps together with the column and table name. In practice the configured dialect has no DDL type registered for the column's JDBC type code, so Hibernate cannot turn the mapping into a SQL type name.","triggerScenarios":"A custom UserType/BasicUserType whose getSqlTypeCode() returns a vendor code the dialect never registered; array, JSON or SQLXML columns used with a dialect that lacks the DDL type; running a legacy Hibernate 5 dialect class on Hibernate 6 where type registration moved to DdlTypeRegistry; hbm2ddl validate/update at SessionFactory boot touching the unmapped column.","commonSituations":"Hibernate 5 to 6 upgrades with an old custom Dialect subclass; custom value types for database-specific types (vendor arrays, special varchar types) registered only partially; using @JdbcTypeCode with an exotic SqlTypes constant; CI booting with hbm2ddl.auto=validate against a new column type.","solutions":["Read the MappingException's cause - it names the real failure (usually an unknown JDBC type code) for the affected column and table.","Use the Hibernate 6+ built-in dialect for your database instead of a Hibernate 5 dialect class, then retry; modern dialects register most codes.","Register the missing DDL type for the code, e.g. via a TypeContributor or dialect customization that registers the column type / DdlType on the DdlTypeRegistry.","Fix the custom type to return a SqlTypes code every dialect can render (e.g. SqlTypes.NUMERIC, SqlTypes.VARCHAR) if the vendor type is not strictly required."],"exampleFix":"// before\npublic class MoneyType implements UserType<Money> {\n    @Override\n    public int getSqlTypeCode() {\n        return 9988; // vendor code the dialect never registered\n    }\n}\n\n// after\npublic class MoneyType implements UserType<Money> {\n    @Override\n    public int getSqlTypeCode() {\n        return SqlTypes.NUMERIC; // a code every dialect can render\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = new MetadataSources(registry)\n            .buildMetadata()\n            .buildSessionFactory();\n} catch (MappingException e) {\n    // message names the column + table; the cause holds the real reason\n    Throwable root = e.getCause() != null ? e.getCause() : e;\n    throw new IllegalStateException(\n        \"Mapping failed: \" + e.getMessage() + \" / cause: \" + root, e);\n}","preventionTips":["Boot the SessionFactory in a smoke test with hbm2ddl.auto=validate in CI so unregistered type codes fail before deployment.","Keep the Hibernate version and its dialect in lockstep; avoid custom Dialect subclasses when a built-in one exists.","Prefer @JdbcTypeCode with standard SqlTypes values over hand-written getSqlTypeCode() overrides.","Register vendor DDL types through a TypeContributor declared in META-INF/services so they load automatically."],"tags":["hibernate","orm","mapping","dialect","jdbc-type","ddl","custom-type"],"backgroundTag":"unsupported-sql-type-code","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}