|
12 | 12 | import java.util.function.Function; |
13 | 13 |
|
14 | 14 | import jakarta.persistence.Embedded; |
| 15 | +import jakarta.persistence.EmbeddedId; |
15 | 16 | import jakarta.persistence.ManyToMany; |
16 | 17 | import jakarta.persistence.ManyToOne; |
17 | 18 | import jakarta.persistence.OneToMany; |
|
20 | 21 | import org.hibernate.AssertionFailure; |
21 | 22 | import org.hibernate.MappingException; |
22 | 23 | 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.*; |
52 | 25 | import org.hibernate.boot.internal.AnyKeyType; |
53 | 26 | import org.hibernate.boot.model.convert.spi.ConverterDescriptor; |
54 | 27 | import org.hibernate.boot.spi.AccessType; |
@@ -1188,30 +1161,43 @@ public Dialect getDialect() { |
1188 | 1161 | } |
1189 | 1162 |
|
1190 | 1163 | 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 ); |
1193 | 1167 | if ( kind == Kind.MAP_KEY ) { |
1194 | 1168 | //noinspection deprecation |
1195 | | - disallowConverter( attribute, MapKeyTemporal.class ); |
1196 | | - disallowConverter( attribute, MapKeyEnumerated.class ); |
| 1169 | + disallowConverter( attribute, MapKeyTemporal.class, autoApply ); |
| 1170 | + disallowConverter( attribute, MapKeyEnumerated.class, autoApply ); |
1197 | 1171 | } |
1198 | 1172 | else { |
1199 | 1173 | //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 ); |
1208 | 1189 | this.converterDescriptor = attributeConverterDescriptor; |
1209 | 1190 | } |
1210 | 1191 |
|
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. |
1212 | 1197 | if ( attribute.hasDirectAnnotationUsage( annotationType ) ) { |
1213 | 1198 | 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)" : "" ) ); |
1215 | 1201 | } |
1216 | 1202 | } |
1217 | 1203 |
|
|
0 commit comments