hibernate/hibernate-orm · error · JdbcTypeRecommendationException
Could not determine recommended JdbcType for Java type '" +
Error message
Could not determine recommended JdbcType for Java type '" + getTypeName() + "'"
What it means
FormatMapperBasedJavaType backs types Hibernate serializes through a FormatMapper (Jackson/Gson JSON), e.g. attributes mapped @JdbcTypeCode(SqlTypes.JSON). It deliberately has no default JDBC type — the storage format must be chosen per attribute. If mapping needs a recommended JdbcType (no explicit @JdbcType/@JdbcTypeCode given), bootstrap fails with JdbcTypeRecommendationException naming the Java type.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/FormatMapperBasedJavaType.java:44
*/
@Incubating
public abstract class FormatMapperBasedJavaType<T> extends AbstractJavaType<T> implements MutabilityPlan<T> {
private final TypeConfiguration typeConfiguration;
public FormatMapperBasedJavaType(
Type type,
MutabilityPlan<T> mutabilityPlan,
TypeConfiguration typeConfiguration) {
super( type, mutabilityPlan );
this.typeConfiguration = typeConfiguration;
}
protected abstract FormatMapper getFormatMapper(TypeConfiguration typeConfiguration);
@Override
public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
throw new JdbcTypeRecommendationException(
"Could not determine recommended JdbcType for Java type '" + getTypeName() + "'"
);
}
private WrapperOptions getWrapperOptions() {
return typeConfiguration.getWrapperOptions();
}
@Override
public String toString(T value) {
return getFormatMapper( typeConfiguration )
.toString( value, this, getWrapperOptions() );
}
@Override
public T fromString(CharSequence string) {
return getFormatMapper( typeConfiguration )
.fromString( string, this, getWrapperOptions() );View on GitHub (pinned to fad1729dce)
Solutions
- Annotate the attribute explicitly: @JdbcTypeCode(SqlTypes.JSON) (or SqlTypes.SQLXML)
- Alternatively specify @JdbcType(yourJsonJdbcType.class) directly
- Override getRecommendedJdbcType() in the custom JavaType to return the intended descriptor instead of throwing
- Register a complete BasicType (JavaType+JdbcType pair) via @TypeRegistration so no recommendation is ever requested
Example fix
// before
@Entity class Event {
@JavaType(MyPayloadJavaType.class) // FormatMapperBasedJavaType subclass
Payload payload; // no JDBC annotation -> JdbcTypeRecommendationException at boot
}
// after
@Entity class Event {
@JavaType(MyPayloadJavaType.class)
@JdbcTypeCode(SqlTypes.JSON)
Payload payload;
} Defensive patterns
Strategy: validation
Validate before calling
static List<String> javaTypeFieldsMissingJdbcAnnotation(Class<?> entity) {
var bad = new ArrayList<String>();
for (var f : entity.getDeclaredFields()) {
boolean hasJavaType = f.isAnnotationPresent(org.hibernate.annotations.JavaType.class);
boolean hasJdbc = f.isAnnotationPresent(org.hibernate.annotations.JdbcType.class)
|| f.isAnnotationPresent(org.hibernate.annotations.JdbcTypeCode.class)
|| f.isAnnotationPresent(jakarta.persistence.Convert.class);
if (hasJavaType && !hasJdbc) bad.add(entity.getSimpleName() + "." + f.getName());
}
return bad; // assert empty before boot
} Try / catch
try {
sessionFactory = metadata.buildSessionFactory();
} catch (org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException e) {
// message names the Java type: add @JdbcTypeCode(SqlTypes.JSON) to that attribute, rebuild
} Prevention
- Always pair a custom JavaType with an explicit @JdbcType/@JdbcTypeCode
- Prefer @TypeRegistration of a complete BasicType over bare JavaType registration
- Run SessionFactory bootstrap in CI to catch missing JDBC-side annotations
When it happens
Trigger: An attribute whose JavaType extends FormatMapperBasedJavaType (custom JSON types, hibernate-types-style registrations) without any @JdbcTypeCode/@JdbcType annotation; schema validation/export requesting the default SQL type of such an attribute; registering only the JavaType half of a custom JSON mapping.
Common situations: Migrating Hibernate 5 UserType JSON mappings to 6.x; using @JavaType on a field without the matching JDBC annotation; third-party type contributions that assume a default JSON column type exists.
Related errors
- Could not determine recommended JdbcType for `" + getTypeNam
- Could not determine recommended JdbcType for '" + getTypeNam
- Unable to determine SQL type name for column '%s' of table '
- Unwrap strategy not known for this Java type: " + getTypeNam
- Wrap strategy not known for this Java type: " + getTypeName(
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e24ca233f88fba3e.
Report an issue: GitHub.