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

UnknownBasicJavaType.getRecommendedJdbcType() throws JdbcTypeRecommendationException whenever Hibernate must infer a JDBC type for a basic attribute whose Java class was never loaded - the descriptor only stores the type name, so no recommendation is possible. It is the mapping-resolution-time symptom of the same unloadable-class problem as 'Unloadable Java type'.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/UnknownBasicJavaType.java:59

	@Override
	public String getTypeName() {
		return typeName;
	}

	@Override
	public Type getJavaType() {
		final Type type = super.getJavaType();
		if ( type == null ) {
			throw new UnsupportedOperationException( "Unloadable Java type: " + typeName );
		}
		else {
			return type;
		}
	}

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

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

	@Override
	public <X> T wrap(X value, WrapperOptions options) {
		final var javaTypeClass = getJavaTypeClass();
		if ( javaTypeClass.isInstance( value ) ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Fix the underlying class-loading problem (class on classpath, correct name) - this exception is only a downstream symptom.
  2. Pin the JDBC type explicitly so inference is skipped: @JdbcType, @JdbcTypeCode, or columnDefinition in orm.xml.
  3. If it is a custom type, register a full BasicType/JavaType in a TypeContributor instead of relying on name-only resolution.

Example fix

// before: Hibernate must infer the JdbcType for a type known only by name
@Embeddable
public class Money {
    @Column(name = "currency")
    Currency currency; // resolved as UnknownBasicJavaType under a broken classloader
}

// after: declare the JDBC type explicitly to bypass inference
@Column(name = "currency")
@JdbcTypeCode(SqlTypes.VARCHAR)
String currencyCode;
Defensive patterns

Strategy: try-catch

Validate before calling

// Before bootstrap, confirm the Java type is actually loadable
try {
    Class.forName(typeName, false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
    throw new IllegalStateException("Cannot infer JDBC type; class missing: " + typeName, e);
}

Try / catch

try {
    metadata.buildSessionFactory();
} catch (org.hibernate.type.descriptor.jdbc.JdbcTypeRecommendationException e) {
    // message names the Java type whose JdbcType could not be inferred:
    // make the class loadable or annotate the attribute with an explicit @JdbcType/@JdbcTypeCode
}

Prevention

When it happens

Trigger: An attribute whose Java class failed to load (registered as UnknownBasicJavaType) combined with JDBC-type inference: schema validation/creation (hibernate.hbm2ddl.auto), binding, or mapping-model resolution asking the JavaType for its recommended JdbcType because no explicit @JdbcType/@JdbcTypeCode is set.

Common situations: The same classpath/classloader mismatches that produce 'Unloadable Java type' - offline tooling, containers, native image; custom basic types registered only by name in a TypeContributor; Hibernate version upgrades that changed where inference is triggered during bootstrap.

Related errors


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