hibernate/hibernate-orm · error · IllegalArgumentException
Unknown type nullability code [${code}] encountered
Error message
Unknown type nullability code [${code}] encountered What it means
TypeNullability.interpret(short) maps the NULLABLE column of DatabaseMetaData.getTypeInfo() onto an enum, accepting only the three JDBC constants: typeNoNulls (0), typeNullable (1), and typeNullableUnknown (2). Any other short value throws IllegalArgumentException. It fires when JDBC metadata supplied by the driver contains a nullability code outside the standard, i.e. a driver that does not conform to the JDBC spec.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/TypeNullability.java:44
* It is unknown if the data type accepts nulls
* @see DatabaseMetaData#typeNullableUnknown
*/
UNKNOWN;
/**
* Based on the code retrieved from {@link DatabaseMetaData#getTypeInfo()} for the {@code NULLABLE}
* column, return the appropriate enum.
*
* @param code The retrieved code value.
*
* @return The corresponding enum.
*/
public static TypeNullability interpret(short code) {
return switch (code) {
case DatabaseMetaData.typeNullable -> NULLABLE;
case DatabaseMetaData.typeNoNulls -> NON_NULLABLE;
case DatabaseMetaData.typeNullableUnknown -> UNKNOWN;
default -> throw new IllegalArgumentException( "Unknown type nullability code [" + code + "] encountered" );
};
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Print the raw NULLABLE values from DriverManager-based getTypeInfo() to confirm which code the driver emits
- Upgrade or replace the JDBC driver with a spec-conformant build
- If you own the calling code, guard unknown codes yourself and fall back to UNKNOWN instead of calling interpret blindly
- Report the nonstandard code to the driver vendor
Example fix
// before
short code = rs.getShort("NULLABLE");
TypeNullability tn = TypeNullability.interpret(code); // throws for unknown codes
// after
short code = rs.getShort("NULLABLE");
TypeNullability tn = switch (code) {
case DatabaseMetaData.typeNoNulls -> TypeNullability.NON_NULLABLE;
case DatabaseMetaData.typeNullable -> TypeNullability.NULLABLE;
case DatabaseMetaData.typeNullableUnknown -> TypeNullability.UNKNOWN;
default -> TypeNullability.UNKNOWN; // tolerate nonstandard driver codes
}; Defensive patterns
Strategy: validation
Validate before calling
static java.util.Optional<TypeNullability> tryInterpret(short code) {
return switch (code) {
case DatabaseMetaData.typeNoNulls -> java.util.Optional.of(TypeNullability.NON_NULLABLE);
case DatabaseMetaData.typeNullable -> java.util.Optional.of(TypeNullability.NULLABLE);
case DatabaseMetaData.typeNullableUnknown -> java.util.Optional.of(TypeNullability.UNKNOWN);
default -> java.util.Optional.empty(); // nonstandard driver code: skip
};
} Try / catch
try {
nullability = TypeNullability.interpret(code);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("nullability code")) {
nullability = TypeNullability.UNKNOWN; // degrade instead of aborting metadata scans
} else {
throw e;
}
} Prevention
- Log the raw NULLABLE values from getTypeInfo() when integrating a new driver
- Guard metadata interpretation with a default branch instead of trusting spec conformance
- Keep the JDBC driver current with database upgrades to avoid vendor-specific metadata codes
When it happens
Trigger: Calling TypeNullability.interpret(code) with a raw value read from the NULLABLE column of getTypeInfo(); drivers that return vendor-specific codes, garbage, or derived values instead of 0/1/2; metadata-extraction or reverse-engineering tools that iterate getTypeInfo() results and feed them to this interpreter.
Common situations: Exotic or legacy JDBC drivers (ODBC bridge, old Informix/Progress/OpenEdge builds, minimal community drivers) whose getTypeInfo() output deviates from the spec; database upgrades where the driver version changed metadata behavior; custom tooling scanning database type metadata.
Related errors
- startTimeNanos [${startTimeNanos}] should be greater than 0
- JDBC driver does not support named parameters for setArray.
- Informix only supports the case insensitive flag 'i' as lite
- #buildNamedQueryRepository should not be called on InFlightM
- You should not be building a SessionFactory from an in-fligh
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/6e2cec9e6ceafd9d.
Report an issue: GitHub.