hibernate/hibernate-orm · error · JdbcTypeRecommendationException

Could not determine recommended JdbcType for '" + getTypeNam

Error message

Could not determine recommended JdbcType for '" + getTypeName() + "'"

What it means

JavaTypeBasicAdaptor is a bare fallback JavaType: it describes a Java class to Hibernate with no JDBC knowledge at all. Whenever mapping requests a recommended JdbcType from it — an attribute of that class with no @JdbcType/@JdbcTypeCode and no complete BasicType registered — bootstrap fails with JdbcTypeRecommendationException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeBasicAdaptor.java:30

/**
 * {@link AbstractClassJavaType} for cases where we do not know a proper
 * {@link org.hibernate.type.descriptor.java.JavaType} for a given Java type.
 *
 * @author Steve Ebersole
 */
public class JavaTypeBasicAdaptor<T> extends AbstractClassJavaType<T> {
	public JavaTypeBasicAdaptor(Class<T> type) {
		super( type );
	}

	public JavaTypeBasicAdaptor(Class<T> type, MutabilityPlan<T> mutabilityPlan) {
		super( type, mutabilityPlan );
	}

	@Override
	public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
		throw new JdbcTypeRecommendationException(
				"Could not determine recommended JdbcType for '" + getTypeName() + "'"
		);
	}

	@Override
	public boolean useObjectEqualsHashCode() {
		return true;
	}

	@Override
	public <X> X unwrap(T value, Class<X> type, WrapperOptions options) {
		throw new UnsupportedOperationException(
				"Unwrap strategy not known for this Java type: " + getTypeName()
		);
	}

	@Override
	public <X> T wrap(X value, WrapperOptions options) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add the JDBC half: @JdbcType or @JdbcTypeCode on the attribute
  2. Register a complete BasicType (JavaType + JdbcType) via @TypeRegistration instead of a bare JavaType
  3. Or add an AttributeConverter to a supported basic type (String/Long/...), which supplies the JDBC side implicitly

Example fix

// before
@JavaType(MoneyJavaType.class)
Money price; // adaptor has no recommended JDBC type -> throws at boot

// after
@JavaType(MoneyJavaType.class)
@JdbcTypeCode(SqlTypes.NUMERIC)
Money price;
Defensive patterns

Strategy: validation

Validate before calling

static List<String> incompleteTypeMappings(Class<?> entity) {
    var bad = new ArrayList<String>();
    for (var f : entity.getDeclaredFields()) {
        boolean needsJdbc = 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)
            || f.isAnnotationPresent(org.hibernate.annotations.Type.class);
        if (needsJdbc && !hasJdbc) bad.add(entity.getSimpleName() + "." + f.getName());
    }
    return bad;
}

Try / catch

try {
    metadata.buildSessionFactory();
} catch (org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException e) {
    // add @JdbcType/@JdbcTypeCode to the field for the type named in the message, then rebuild
}

Prevention

When it happens

Trigger: Registering only a JavaType for a class (@JavaType, JavaTypeRegistry.addDescriptor) and mapping an attribute of that class without any JDBC-side annotation; DDL export or schema validation asking for the default SQL type of such an attribute.

Common situations: Custom value objects expected to 'just work' as basic types; partial registrations copied from hibernate-types-style integrations; annotating @JavaType while forgetting that a JavaType alone never defines storage.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/61aae558d818e69d. Report an issue: GitHub.