Skip to content

Commit abf5543

Browse files
committed
improve the error message and add comments
1 parent 9ff21ad commit abf5543

File tree

5 files changed

+45
-48
lines changed

5 files changed

+45
-48
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/convert/internal/AutoApplicableConverterDescriptorBypassedImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public class AutoApplicableConverterDescriptorBypassedImpl implements AutoApplic
2424
private AutoApplicableConverterDescriptorBypassedImpl() {
2525
}
2626

27+
@Override
28+
public boolean isAutoApplicable() {
29+
return false;
30+
}
31+
2732
@Override
2833
public ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(
2934
MemberDetails memberDetails,

hibernate-core/src/main/java/org/hibernate/boot/model/convert/internal/AutoApplicableConverterDescriptorStandardImpl.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public AutoApplicableConverterDescriptorStandardImpl(ConverterDescriptor linkedC
3333
this.linkedConverterDescriptor = linkedConverterDescriptor;
3434
}
3535

36+
@Override
37+
public boolean isAutoApplicable() {
38+
return true;
39+
}
40+
3641
@Override
3742
public ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(
3843
MemberDetails memberDetails,
@@ -51,16 +56,16 @@ public ConverterDescriptor getAutoAppliedConverterDescriptorForCollectionElement
5156
final ResolvedMember<?> collectionMember = resolveMember( memberDetails, context );
5257

5358
final ResolvedType elementType;
54-
Class<?> erasedType = collectionMember.getType().getErasedType();
59+
final Class<?> erasedType = collectionMember.getType().getErasedType();
5560
if ( Map.class.isAssignableFrom( erasedType ) ) {
56-
List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
61+
final List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
5762
if ( typeArguments.size() < 2 ) {
5863
return null;
5964
}
6065
elementType = typeArguments.get( 1 );
6166
}
6267
else if ( Collection.class.isAssignableFrom( erasedType ) ) {
63-
List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Collection.class);
68+
final List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Collection.class);
6469
if ( typeArguments.isEmpty() ) {
6570
return null;
6671
}
@@ -87,7 +92,7 @@ public ConverterDescriptor getAutoAppliedConverterDescriptorForMapKey(
8792
final ResolvedType keyType;
8893

8994
if ( Map.class.isAssignableFrom( collectionMember.getType().getErasedType() ) ) {
90-
List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
95+
final List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
9196
if ( typeArguments.isEmpty() ) {
9297
return null;
9398
}

hibernate-core/src/main/java/org/hibernate/boot/model/convert/spi/AutoApplicableConverterDescriptor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* @author Steve Ebersole
1414
*/
1515
public interface AutoApplicableConverterDescriptor {
16+
boolean isAutoApplicable();
1617
ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(MemberDetails memberDetails, MetadataBuildingContext context);
1718
ConverterDescriptor getAutoAppliedConverterDescriptorForCollectionElement(MemberDetails memberDetails, MetadataBuildingContext context);
1819
ConverterDescriptor getAutoAppliedConverterDescriptorForMapKey(MemberDetails memberDetails, MetadataBuildingContext context);

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AbstractPropertyHolder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
8787

8888
@Override
8989
public ConverterDescriptor resolveAttributeConverterDescriptor(MemberDetails attributeMember) {
90-
AttributeConversionInfo info = locateAttributeConversionInfo( attributeMember );
90+
final AttributeConversionInfo info = locateAttributeConversionInfo( attributeMember );
9191
if ( info != null ) {
9292
if ( info.isConversionDisabled() ) {
9393
return null;

hibernate-core/src/main/java/org/hibernate/boot/model/internal/BasicValueBinder.java

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.function.Function;
1313

1414
import jakarta.persistence.Embedded;
15+
import jakarta.persistence.EmbeddedId;
1516
import jakarta.persistence.ManyToMany;
1617
import jakarta.persistence.ManyToOne;
1718
import jakarta.persistence.OneToMany;
@@ -20,35 +21,7 @@
2021
import org.hibernate.AssertionFailure;
2122
import org.hibernate.MappingException;
2223
import org.hibernate.TimeZoneStorageStrategy;
23-
import org.hibernate.annotations.AnyDiscriminator;
24-
import org.hibernate.annotations.AnyKeyJavaClass;
25-
import org.hibernate.annotations.AnyKeyJavaType;
26-
import org.hibernate.annotations.AnyKeyJdbcType;
27-
import org.hibernate.annotations.AnyKeyJdbcTypeCode;
28-
import org.hibernate.annotations.CollectionId;
29-
import org.hibernate.annotations.CollectionIdJavaType;
30-
import org.hibernate.annotations.CollectionIdJdbcType;
31-
import org.hibernate.annotations.CollectionIdJdbcTypeCode;
32-
import org.hibernate.annotations.CollectionIdMutability;
33-
import org.hibernate.annotations.CollectionIdType;
34-
import org.hibernate.annotations.Immutable;
35-
import org.hibernate.annotations.JdbcTypeCode;
36-
import org.hibernate.annotations.ListIndexJavaType;
37-
import org.hibernate.annotations.ListIndexJdbcType;
38-
import org.hibernate.annotations.ListIndexJdbcTypeCode;
39-
import org.hibernate.annotations.MapKeyJavaType;
40-
import org.hibernate.annotations.MapKeyJdbcType;
41-
import org.hibernate.annotations.MapKeyJdbcTypeCode;
42-
import org.hibernate.annotations.MapKeyMutability;
43-
import org.hibernate.annotations.MapKeyType;
44-
import org.hibernate.annotations.Mutability;
45-
import org.hibernate.annotations.Nationalized;
46-
import org.hibernate.annotations.PartitionKey;
47-
import org.hibernate.annotations.Target;
48-
import org.hibernate.annotations.TimeZoneColumn;
49-
import org.hibernate.annotations.TimeZoneStorage;
50-
import org.hibernate.annotations.TimeZoneStorageType;
51-
import org.hibernate.annotations.Type;
24+
import org.hibernate.annotations.*;
5225
import org.hibernate.boot.internal.AnyKeyType;
5326
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
5427
import org.hibernate.boot.spi.AccessType;
@@ -1188,30 +1161,43 @@ public Dialect getDialect() {
11881161
}
11891162

11901163
private void applyJpaConverter(MemberDetails attribute, ConverterDescriptor attributeConverterDescriptor) {
1191-
disallowConverter( attribute, Id.class );
1192-
disallowConverter( attribute, Version.class );
1164+
final boolean autoApply = attributeConverterDescriptor.getAutoApplyDescriptor().isAutoApplicable();
1165+
disallowConverter( attribute, Id.class, autoApply );
1166+
disallowConverter( attribute, Version.class, autoApply );
11931167
if ( kind == Kind.MAP_KEY ) {
11941168
//noinspection deprecation
1195-
disallowConverter( attribute, MapKeyTemporal.class );
1196-
disallowConverter( attribute, MapKeyEnumerated.class );
1169+
disallowConverter( attribute, MapKeyTemporal.class, autoApply );
1170+
disallowConverter( attribute, MapKeyEnumerated.class, autoApply );
11971171
}
11981172
else {
11991173
//noinspection deprecation
1200-
disallowConverter( attribute, Temporal.class );
1201-
disallowConverter( attribute, Enumerated.class );
1202-
disallowConverter( attribute, Embedded.class );
1203-
disallowConverter( attribute, ManyToOne.class );
1204-
disallowConverter( attribute, OneToOne.class );
1205-
disallowConverter( attribute, OneToMany.class );
1206-
disallowConverter( attribute, ManyToMany.class );
1207-
}
1174+
disallowConverter( attribute, Temporal.class, autoApply );
1175+
disallowConverter( attribute, Enumerated.class, autoApply );
1176+
disallowConverter( attribute, ManyToOne.class, autoApply );
1177+
disallowConverter( attribute, OneToOne.class, autoApply );
1178+
disallowConverter( attribute, OneToMany.class, autoApply );
1179+
disallowConverter( attribute, ManyToMany.class, autoApply );
1180+
// Note that @Convert is only allowed in conjunction with
1181+
// @Embedded if it specifies a field using attributeName
1182+
disallowConverter( attribute, Embedded.class, autoApply );
1183+
disallowConverter( attribute, EmbeddedId.class, autoApply );
1184+
}
1185+
// I assume that these do not work with converters (no tests)
1186+
disallowConverter( attribute, Struct.class, autoApply );
1187+
disallowConverter( attribute, Array.class, autoApply );
1188+
disallowConverter( attribute, Any.class, autoApply );
12081189
this.converterDescriptor = attributeConverterDescriptor;
12091190
}
12101191

1211-
void disallowConverter(MemberDetails attribute, Class<? extends Annotation> annotationType) {
1192+
void disallowConverter(MemberDetails attribute, Class<? extends Annotation> annotationType, boolean autoApply) {
1193+
// NOTE: A really faithful reading of the JPA spec is that we should
1194+
// just silently ignore any auto-apply converter which matches
1195+
// one of the disallowed attribute types, but for now let's be
1196+
// a bit more fussy/helpful, and see how many people complain.
12121197
if ( attribute.hasDirectAnnotationUsage( annotationType ) ) {
12131198
throw new AnnotationException( "'AttributeConverter' not allowed for attribute '" + attribute.getName()
1214-
+ "' annotated '@" + annotationType.getName() + "'" );
1199+
+ "' annotated '@" + annotationType.getName() + "'"
1200+
+ ( autoApply ? " (use '@Convert(disableConversion=true)' to suppress this error)" : "" ) );
12151201
}
12161202
}
12171203

0 commit comments

Comments
 (0)