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
- Keep exactly one type specification per attribute: @CustomType alone, or @Type/@JdbcTypeCode alone.
- Remove the legacy @Type/@TypeDef where @CustomType is introduced.
- 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
- Use exactly one type specification per attribute
- Remove legacy @Type/@TypeDef when introducing @CustomType
- In programmatic mapping, set custom types before any type-name resolution
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
- Column mappings for property '${propertyName}' mix updatable
- Error processing @TypeBinderType annotation '%s' for embedda
- Error processing @TypeBinderType annotation '%s' for entity
- error processing @AttributeBinderType annotation '%s' for at
- Wrong kind of binder for annotation type: '%s' does not acce
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/69d304eb31b7b6cd.
Report an issue: GitHub.