improve the error message and add comments
This commit is contained in:
parent
9ff21ad449
commit
abf55433a2
|
@ -24,6 +24,11 @@ public class AutoApplicableConverterDescriptorBypassedImpl implements AutoApplic
|
||||||
private AutoApplicableConverterDescriptorBypassedImpl() {
|
private AutoApplicableConverterDescriptorBypassedImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAutoApplicable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(
|
public ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(
|
||||||
MemberDetails memberDetails,
|
MemberDetails memberDetails,
|
||||||
|
|
|
@ -33,6 +33,11 @@ public class AutoApplicableConverterDescriptorStandardImpl implements AutoApplic
|
||||||
this.linkedConverterDescriptor = linkedConverterDescriptor;
|
this.linkedConverterDescriptor = linkedConverterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAutoApplicable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(
|
public ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(
|
||||||
MemberDetails memberDetails,
|
MemberDetails memberDetails,
|
||||||
|
@ -51,16 +56,16 @@ public class AutoApplicableConverterDescriptorStandardImpl implements AutoApplic
|
||||||
final ResolvedMember<?> collectionMember = resolveMember( memberDetails, context );
|
final ResolvedMember<?> collectionMember = resolveMember( memberDetails, context );
|
||||||
|
|
||||||
final ResolvedType elementType;
|
final ResolvedType elementType;
|
||||||
Class<?> erasedType = collectionMember.getType().getErasedType();
|
final Class<?> erasedType = collectionMember.getType().getErasedType();
|
||||||
if ( Map.class.isAssignableFrom( erasedType ) ) {
|
if ( Map.class.isAssignableFrom( erasedType ) ) {
|
||||||
List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
|
final List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
|
||||||
if ( typeArguments.size() < 2 ) {
|
if ( typeArguments.size() < 2 ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
elementType = typeArguments.get( 1 );
|
elementType = typeArguments.get( 1 );
|
||||||
}
|
}
|
||||||
else if ( Collection.class.isAssignableFrom( erasedType ) ) {
|
else if ( Collection.class.isAssignableFrom( erasedType ) ) {
|
||||||
List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Collection.class);
|
final List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Collection.class);
|
||||||
if ( typeArguments.isEmpty() ) {
|
if ( typeArguments.isEmpty() ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +92,7 @@ public class AutoApplicableConverterDescriptorStandardImpl implements AutoApplic
|
||||||
final ResolvedType keyType;
|
final ResolvedType keyType;
|
||||||
|
|
||||||
if ( Map.class.isAssignableFrom( collectionMember.getType().getErasedType() ) ) {
|
if ( Map.class.isAssignableFrom( collectionMember.getType().getErasedType() ) ) {
|
||||||
List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
|
final List<ResolvedType> typeArguments = collectionMember.getType().typeParametersFor(Map.class);
|
||||||
if ( typeArguments.isEmpty() ) {
|
if ( typeArguments.isEmpty() ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.models.spi.MemberDetails;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface AutoApplicableConverterDescriptor {
|
public interface AutoApplicableConverterDescriptor {
|
||||||
|
boolean isAutoApplicable();
|
||||||
ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(MemberDetails memberDetails, MetadataBuildingContext context);
|
ConverterDescriptor getAutoAppliedConverterDescriptorForAttribute(MemberDetails memberDetails, MetadataBuildingContext context);
|
||||||
ConverterDescriptor getAutoAppliedConverterDescriptorForCollectionElement(MemberDetails memberDetails, MetadataBuildingContext context);
|
ConverterDescriptor getAutoAppliedConverterDescriptorForCollectionElement(MemberDetails memberDetails, MetadataBuildingContext context);
|
||||||
ConverterDescriptor getAutoAppliedConverterDescriptorForMapKey(MemberDetails memberDetails, MetadataBuildingContext context);
|
ConverterDescriptor getAutoAppliedConverterDescriptorForMapKey(MemberDetails memberDetails, MetadataBuildingContext context);
|
||||||
|
|
|
@ -87,7 +87,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConverterDescriptor resolveAttributeConverterDescriptor(MemberDetails attributeMember) {
|
public ConverterDescriptor resolveAttributeConverterDescriptor(MemberDetails attributeMember) {
|
||||||
AttributeConversionInfo info = locateAttributeConversionInfo( attributeMember );
|
final AttributeConversionInfo info = locateAttributeConversionInfo( attributeMember );
|
||||||
if ( info != null ) {
|
if ( info != null ) {
|
||||||
if ( info.isConversionDisabled() ) {
|
if ( info.isConversionDisabled() ) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import jakarta.persistence.Embedded;
|
import jakarta.persistence.Embedded;
|
||||||
|
import jakarta.persistence.EmbeddedId;
|
||||||
import jakarta.persistence.ManyToMany;
|
import jakarta.persistence.ManyToMany;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
|
@ -20,35 +21,7 @@ import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.TimeZoneStorageStrategy;
|
import org.hibernate.TimeZoneStorageStrategy;
|
||||||
import org.hibernate.annotations.AnyDiscriminator;
|
import org.hibernate.annotations.*;
|
||||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
|
||||||
import org.hibernate.annotations.AnyKeyJavaType;
|
|
||||||
import org.hibernate.annotations.AnyKeyJdbcType;
|
|
||||||
import org.hibernate.annotations.AnyKeyJdbcTypeCode;
|
|
||||||
import org.hibernate.annotations.CollectionId;
|
|
||||||
import org.hibernate.annotations.CollectionIdJavaType;
|
|
||||||
import org.hibernate.annotations.CollectionIdJdbcType;
|
|
||||||
import org.hibernate.annotations.CollectionIdJdbcTypeCode;
|
|
||||||
import org.hibernate.annotations.CollectionIdMutability;
|
|
||||||
import org.hibernate.annotations.CollectionIdType;
|
|
||||||
import org.hibernate.annotations.Immutable;
|
|
||||||
import org.hibernate.annotations.JdbcTypeCode;
|
|
||||||
import org.hibernate.annotations.ListIndexJavaType;
|
|
||||||
import org.hibernate.annotations.ListIndexJdbcType;
|
|
||||||
import org.hibernate.annotations.ListIndexJdbcTypeCode;
|
|
||||||
import org.hibernate.annotations.MapKeyJavaType;
|
|
||||||
import org.hibernate.annotations.MapKeyJdbcType;
|
|
||||||
import org.hibernate.annotations.MapKeyJdbcTypeCode;
|
|
||||||
import org.hibernate.annotations.MapKeyMutability;
|
|
||||||
import org.hibernate.annotations.MapKeyType;
|
|
||||||
import org.hibernate.annotations.Mutability;
|
|
||||||
import org.hibernate.annotations.Nationalized;
|
|
||||||
import org.hibernate.annotations.PartitionKey;
|
|
||||||
import org.hibernate.annotations.Target;
|
|
||||||
import org.hibernate.annotations.TimeZoneColumn;
|
|
||||||
import org.hibernate.annotations.TimeZoneStorage;
|
|
||||||
import org.hibernate.annotations.TimeZoneStorageType;
|
|
||||||
import org.hibernate.annotations.Type;
|
|
||||||
import org.hibernate.boot.internal.AnyKeyType;
|
import org.hibernate.boot.internal.AnyKeyType;
|
||||||
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
|
||||||
import org.hibernate.boot.spi.AccessType;
|
import org.hibernate.boot.spi.AccessType;
|
||||||
|
@ -1188,30 +1161,43 @@ public class BasicValueBinder implements JdbcTypeIndicators {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyJpaConverter(MemberDetails attribute, ConverterDescriptor attributeConverterDescriptor) {
|
private void applyJpaConverter(MemberDetails attribute, ConverterDescriptor attributeConverterDescriptor) {
|
||||||
disallowConverter( attribute, Id.class );
|
final boolean autoApply = attributeConverterDescriptor.getAutoApplyDescriptor().isAutoApplicable();
|
||||||
disallowConverter( attribute, Version.class );
|
disallowConverter( attribute, Id.class, autoApply );
|
||||||
|
disallowConverter( attribute, Version.class, autoApply );
|
||||||
if ( kind == Kind.MAP_KEY ) {
|
if ( kind == Kind.MAP_KEY ) {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
disallowConverter( attribute, MapKeyTemporal.class );
|
disallowConverter( attribute, MapKeyTemporal.class, autoApply );
|
||||||
disallowConverter( attribute, MapKeyEnumerated.class );
|
disallowConverter( attribute, MapKeyEnumerated.class, autoApply );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
disallowConverter( attribute, Temporal.class );
|
disallowConverter( attribute, Temporal.class, autoApply );
|
||||||
disallowConverter( attribute, Enumerated.class );
|
disallowConverter( attribute, Enumerated.class, autoApply );
|
||||||
disallowConverter( attribute, Embedded.class );
|
disallowConverter( attribute, ManyToOne.class, autoApply );
|
||||||
disallowConverter( attribute, ManyToOne.class );
|
disallowConverter( attribute, OneToOne.class, autoApply );
|
||||||
disallowConverter( attribute, OneToOne.class );
|
disallowConverter( attribute, OneToMany.class, autoApply );
|
||||||
disallowConverter( attribute, OneToMany.class );
|
disallowConverter( attribute, ManyToMany.class, autoApply );
|
||||||
disallowConverter( attribute, ManyToMany.class );
|
// Note that @Convert is only allowed in conjunction with
|
||||||
|
// @Embedded if it specifies a field using attributeName
|
||||||
|
disallowConverter( attribute, Embedded.class, autoApply );
|
||||||
|
disallowConverter( attribute, EmbeddedId.class, autoApply );
|
||||||
}
|
}
|
||||||
|
// I assume that these do not work with converters (no tests)
|
||||||
|
disallowConverter( attribute, Struct.class, autoApply );
|
||||||
|
disallowConverter( attribute, Array.class, autoApply );
|
||||||
|
disallowConverter( attribute, Any.class, autoApply );
|
||||||
this.converterDescriptor = attributeConverterDescriptor;
|
this.converterDescriptor = attributeConverterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disallowConverter(MemberDetails attribute, Class<? extends Annotation> annotationType) {
|
void disallowConverter(MemberDetails attribute, Class<? extends Annotation> annotationType, boolean autoApply) {
|
||||||
|
// NOTE: A really faithful reading of the JPA spec is that we should
|
||||||
|
// just silently ignore any auto-apply converter which matches
|
||||||
|
// one of the disallowed attribute types, but for now let's be
|
||||||
|
// a bit more fussy/helpful, and see how many people complain.
|
||||||
if ( attribute.hasDirectAnnotationUsage( annotationType ) ) {
|
if ( attribute.hasDirectAnnotationUsage( annotationType ) ) {
|
||||||
throw new AnnotationException( "'AttributeConverter' not allowed for attribute '" + attribute.getName()
|
throw new AnnotationException( "'AttributeConverter' not allowed for attribute '" + attribute.getName()
|
||||||
+ "' annotated '@" + annotationType.getName() + "'" );
|
+ "' annotated '@" + annotationType.getName() + "'"
|
||||||
|
+ ( autoApply ? " (use '@Convert(disableConversion=true)' to suppress this error)" : "" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue