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

  1. Annotate the attribute explicitly: @JdbcTypeCode(SqlTypes.JSON) (or SqlTypes.SQLXML)
  2. Alternatively specify @JdbcType(yourJsonJdbcType.class) directly
  3. Override getRecommendedJdbcType() in the custom JavaType to return the intended descriptor instead of throwing
  4. 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

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


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