hibernate/hibernate-orm · error · UnsupportedOperationException

Unsupported attempt to set an explicit-custom-type when valu

Error message

Unsupported attempt to set an explicit-custom-type when value is already resolved

What it means

BasicValue.setExplicitCustomType builds a resolution immediately; once the value already has a resolution (e.g., a type name was set first), setting an explicit custom type is rejected as an unsupported state transition. In practice it means one attribute carries conflicting type specifications.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java:1088

	public void setTypeName(String typeName) {
		if ( isEmpty( typeName ) ) {
			super.setTypeName( typeName );
		}
		else if ( typeName.startsWith( TYPE_NAME_PREFIX ) ) {
			setAttributeConverterDescriptor( typeName );
		}
		else {
			setExplicitTypeName( typeName );
			super.setTypeName( typeName );
		}
	}

	private static int COUNTER;

	public void setExplicitCustomType(Class<? extends UserType<?>> explicitCustomType) {
		if ( explicitCustomType != null ) {
			if ( resolution != null ) {
				throw new UnsupportedOperationException( "Unsupported attempt to set an explicit-custom-type when value is already resolved" );
			}
			else {
				final var parameters = buildCustomTypeProperties();
				resolution = new UserTypeResolution<>(
						new CustomType<>(
								getConfiguredUserTypeBean( explicitCustomType, getTypeAnnotation(), parameters ),
								getTypeConfiguration()
						),
						null,
						parameters
				);
			}
		}
	}

	private Properties buildCustomTypeProperties() {
		final var properties = new Properties();
		if ( isNotEmpty( getTypeParameters() ) ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Keep exactly one type specification per attribute: @CustomType alone, or @Type/@JdbcTypeCode alone.
  2. Remove the legacy @Type/@TypeDef where @CustomType is introduced.
  3. In programmatic mapping, set the custom type before any type-name resolution happens.

Example fix

// before
@Type(MyType.class)
@CustomType(MyUserType.class)
private String phone;

// after
@CustomType(MyUserType.class)
private String phone;
Defensive patterns

Strategy: validation

Validate before calling

static boolean hasConflictingType( Field f ) {
    return f.isAnnotationPresent( Type.class ) && f.isAnnotationPresent( CustomType.class );
}
// run over mapped classes as a startup audit

Prevention

When it happens

Trigger: An attribute annotated with both @Type/@JdbcTypeCode-derived specification and @CustomType, so processing sets the type name first and the custom type second; programmatic mapping calling setTypeName(...) then setExplicitCustomType(...); composed annotations applying type specs twice.

Common situations: Introducing @CustomType over legacy @Type mappings during a Hibernate 6.2+ upgrade; meta-annotated stereotypes stacking type annotations; in-house mapping frameworks mutating BasicValue after resolution.

Related errors


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