HHH-18060 - HbXmlTransformer work
* "special" basic type handling
This commit is contained in:
parent
d25f028222
commit
875e84b930
|
@ -10,8 +10,30 @@ import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Blob;
|
||||||
|
import java.sql.Clob;
|
||||||
|
import java.sql.NClob;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.OffsetTime;
|
||||||
|
import java.time.Year;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Currency;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@ -136,6 +158,41 @@ import org.hibernate.models.spi.MutableClassDetails;
|
||||||
import org.hibernate.models.spi.MutableMemberDetails;
|
import org.hibernate.models.spi.MutableMemberDetails;
|
||||||
import org.hibernate.models.spi.SourceModelBuildingContext;
|
import org.hibernate.models.spi.SourceModelBuildingContext;
|
||||||
import org.hibernate.type.SqlTypes;
|
import org.hibernate.type.SqlTypes;
|
||||||
|
import org.hibernate.type.descriptor.java.BasicJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.BigDecimalJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.BigIntegerJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.BlobJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.BooleanJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ByteJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.CalendarJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.CharacterJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ClassJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ClobJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.CurrencyJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.DateJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.DoubleJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.DurationJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.InetAddressJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.InstantJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.IntegerJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.LocalDateJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.LocalDateTimeJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.LocalTimeJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.LocaleJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.LongJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.NClobJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.OffsetDateTimeJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.OffsetTimeJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ShortJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.StringJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.TimeZoneJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.UrlJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.YearJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ZoneIdJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ZoneOffsetJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaType;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
import jakarta.persistence.AssociationOverride;
|
import jakarta.persistence.AssociationOverride;
|
||||||
import jakarta.persistence.AttributeOverride;
|
import jakarta.persistence.AttributeOverride;
|
||||||
|
@ -146,6 +203,7 @@ import jakarta.persistence.EnumType;
|
||||||
import jakarta.persistence.Index;
|
import jakarta.persistence.Index;
|
||||||
import jakarta.persistence.PrimaryKeyJoinColumn;
|
import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||||
import jakarta.persistence.SecondaryTable;
|
import jakarta.persistence.SecondaryTable;
|
||||||
|
import jakarta.persistence.Temporal;
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
import jakarta.persistence.UniqueConstraint;
|
import jakarta.persistence.UniqueConstraint;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
@ -244,20 +302,305 @@ public class XmlAnnotationHelper {
|
||||||
JaxbUserTypeImpl jaxbType,
|
JaxbUserTypeImpl jaxbType,
|
||||||
MutableMemberDetails memberDetails,
|
MutableMemberDetails memberDetails,
|
||||||
XmlDocumentContext xmlDocumentContext) {
|
XmlDocumentContext xmlDocumentContext) {
|
||||||
if ( jaxbType == null ) {
|
if ( jaxbType == null || StringHelper.isEmpty( jaxbType.getValue() ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean wasSpecialCase = handleSpecialBasicTypeCases( jaxbType, memberDetails, xmlDocumentContext );
|
||||||
|
if ( wasSpecialCase ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClassDetails userTypeImpl = resolveJavaType( jaxbType.getValue(), xmlDocumentContext );
|
||||||
|
assert userTypeImpl.isImplementor( UserType.class );
|
||||||
final TypeAnnotation typeAnn = (TypeAnnotation) memberDetails.applyAnnotationUsage(
|
final TypeAnnotation typeAnn = (TypeAnnotation) memberDetails.applyAnnotationUsage(
|
||||||
HibernateAnnotations.TYPE,
|
HibernateAnnotations.TYPE,
|
||||||
xmlDocumentContext.getModelBuildingContext()
|
xmlDocumentContext.getModelBuildingContext()
|
||||||
);
|
);
|
||||||
|
|
||||||
final ClassDetails userTypeImpl = resolveJavaType( jaxbType.getValue(), xmlDocumentContext );
|
|
||||||
typeAnn.value( userTypeImpl.toJavaClass() );
|
typeAnn.value( userTypeImpl.toJavaClass() );
|
||||||
typeAnn.parameters( collectParameters( jaxbType.getParameters(), xmlDocumentContext ) );
|
typeAnn.parameters( collectParameters( jaxbType.getParameters(), xmlDocumentContext ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean handleSpecialBasicTypeCases(
|
||||||
|
JaxbUserTypeImpl jaxbType,
|
||||||
|
MutableMemberDetails memberDetails,
|
||||||
|
XmlDocumentContext xmlDocumentContext) {
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "char" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "character" )
|
||||||
|
|| Character.class.getName().equalsIgnoreCase( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, CharacterJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "string" )
|
||||||
|
|| String.class.getName().equalsIgnoreCase( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, StringJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "byte" )
|
||||||
|
|| Byte.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ByteJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "boolean" )
|
||||||
|
|| Boolean.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, BooleanJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "short" )
|
||||||
|
|| Short.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ShortJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "int" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "integer" )
|
||||||
|
|| Integer.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, IntegerJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "long" )
|
||||||
|
|| Long.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, LongJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "double" )
|
||||||
|
|| Double.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, DoubleJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "float" )
|
||||||
|
|| Float.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, DoubleJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "biginteger" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "big_integer" )
|
||||||
|
|| BigInteger.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, BigIntegerJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "bigdecimal" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "big_decimal" )
|
||||||
|
|| BigDecimal.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, BigDecimalJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "uuid" )
|
||||||
|
|| UUID.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, UUIDJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "url" )
|
||||||
|
|| URL.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, UrlJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "inet" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "inetaddress" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "inet_address" )
|
||||||
|
|| InetAddress.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, InetAddressJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "currency" )
|
||||||
|
|| Currency.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, CurrencyJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "locale" )
|
||||||
|
|| Locale.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, LocaleJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "class" )
|
||||||
|
|| Class.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ClassJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "blob" )
|
||||||
|
|| Blob.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, BlobJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "clob" )
|
||||||
|
|| Clob.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ClobJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "nclob" )
|
||||||
|
|| NClob.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, NClobJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "instant" )
|
||||||
|
|| Instant.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, InstantJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "duration" )
|
||||||
|
|| Duration.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, DurationJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "year" )
|
||||||
|
|| Year.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, YearJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "localdatetime" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "local_date_time" )
|
||||||
|
|| LocalDateTime.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, LocalDateTimeJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "localdate" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "local_date" )
|
||||||
|
|| LocalDate.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, LocalDateJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "localtime" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "local_time" )
|
||||||
|
|| LocalTime.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, LocalTimeJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "zoneddatetime" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "zoned_date_time" )
|
||||||
|
|| ZonedDateTime.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ZonedDateTimeJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "offsetdatetime" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "offset_date_time" )
|
||||||
|
|| OffsetDateTime.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, OffsetDateTimeJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "offsettime" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "offset_time" )
|
||||||
|
|| OffsetTime.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, OffsetTimeJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "zoneid" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "zone_id" )
|
||||||
|
|| ZoneId.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ZoneIdJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "zoneoffset" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "zone_offset" )
|
||||||
|
|| ZoneOffset.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, ZoneOffsetJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "timestamp" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "time_stamp" )
|
||||||
|
|| java.util.Date.class.getName().equals( jaxbType.getValue() )
|
||||||
|
|| Timestamp.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, DateJavaType.class, xmlDocumentContext );
|
||||||
|
applyTemporalPrecision( memberDetails, TemporalType.TIMESTAMP, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "date" )
|
||||||
|
|| java.sql.Date.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, DateJavaType.class, xmlDocumentContext );
|
||||||
|
applyTemporalPrecision( memberDetails, TemporalType.DATE, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "time" )
|
||||||
|
|| java.sql.Time.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, DateJavaType.class, xmlDocumentContext );
|
||||||
|
applyTemporalPrecision( memberDetails, TemporalType.TIME, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "calendar" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "gregoriancalendar" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "gregorian_calendar" )
|
||||||
|
|| Calendar.class.getName().equals( jaxbType.getValue() )
|
||||||
|
|| GregorianCalendar.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, CalendarJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jaxbType.getValue().equalsIgnoreCase( "timezone" )
|
||||||
|
|| jaxbType.getValue().equalsIgnoreCase( "time_zone" )
|
||||||
|
|| TimeZone.class.getName().equals( jaxbType.getValue() ) ) {
|
||||||
|
applyJavaTypeAnnotation( memberDetails, TimeZoneJavaType.class, xmlDocumentContext );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyJavaTypeAnnotation(
|
||||||
|
MutableMemberDetails memberDetails,
|
||||||
|
Class<? extends BasicJavaType<?>> descriptor,
|
||||||
|
XmlDocumentContext xmlDocumentContext) {
|
||||||
|
final JavaTypeAnnotation javaTypeAnnotation = (JavaTypeAnnotation) memberDetails.applyAnnotationUsage(
|
||||||
|
HibernateAnnotations.JAVA_TYPE,
|
||||||
|
xmlDocumentContext.getModelBuildingContext()
|
||||||
|
);
|
||||||
|
javaTypeAnnotation.value( descriptor );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyTemporalPrecision(MutableMemberDetails memberDetails, TemporalType temporalType, XmlDocumentContext xmlDocumentContext) {
|
||||||
|
final Temporal directUsage = memberDetails.getDirectAnnotationUsage( Temporal.class );
|
||||||
|
if ( directUsage != null ) {
|
||||||
|
// make sure they match
|
||||||
|
if ( directUsage.value() != temporalType ) {
|
||||||
|
throw new org.hibernate.MappingException( String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Mismatch in expected TemporalType on %s; found %s and %s",
|
||||||
|
memberDetails,
|
||||||
|
directUsage.value(),
|
||||||
|
temporalType
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final TemporalJpaAnnotation temporalAnnotation = (TemporalJpaAnnotation) memberDetails.applyAnnotationUsage(
|
||||||
|
JpaAnnotations.TEMPORAL,
|
||||||
|
xmlDocumentContext.getModelBuildingContext()
|
||||||
|
);
|
||||||
|
temporalAnnotation.value( temporalType );
|
||||||
|
}
|
||||||
|
|
||||||
private static final Parameter[] NO_PARAMETERS = new Parameter[0];
|
private static final Parameter[] NO_PARAMETERS = new Parameter[0];
|
||||||
|
|
||||||
public static Parameter[] collectParameters(
|
public static Parameter[] collectParameters(
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.boot.models.annotations.internal.BasicJpaAnnotation;
|
||||||
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
|
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
|
||||||
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
|
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
|
||||||
import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
|
import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.models.spi.MutableClassDetails;
|
import org.hibernate.models.spi.MutableClassDetails;
|
||||||
import org.hibernate.models.spi.MutableMemberDetails;
|
import org.hibernate.models.spi.MutableMemberDetails;
|
||||||
|
|
||||||
|
@ -33,8 +34,12 @@ public class BasicIdAttributeProcessing {
|
||||||
AccessType classAccessType,
|
AccessType classAccessType,
|
||||||
XmlDocumentContext xmlDocumentContext) {
|
XmlDocumentContext xmlDocumentContext) {
|
||||||
final AccessType accessType = coalesce( jaxbId.getAccess(), classAccessType );
|
final AccessType accessType = coalesce( jaxbId.getAccess(), classAccessType );
|
||||||
|
final String idAttributeName = StringHelper.isNotEmpty( jaxbId.getName() )
|
||||||
|
? jaxbId.getName()
|
||||||
|
: "id";
|
||||||
|
|
||||||
final MutableMemberDetails memberDetails = XmlProcessingHelper.getAttributeMember(
|
final MutableMemberDetails memberDetails = XmlProcessingHelper.getAttributeMember(
|
||||||
jaxbId.getName(),
|
idAttributeName,
|
||||||
accessType,
|
accessType,
|
||||||
declarer
|
declarer
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.boot.models.hbm.type;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class EntityWithElementCollections {
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private List<String> listOfStrings;
|
||||||
|
private List<Integer> listOfIntegers;
|
||||||
|
private List<Double> listOfDoubles;
|
||||||
|
private List<URL> listOfUrls;
|
||||||
|
private List<UUID> listOfUuids;
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.boot.models.hbm.type;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.mapping.Collection;
|
||||||
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.mapping.RootClass;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
|
import org.hibernate.type.SqlTypes;
|
||||||
|
import org.hibernate.type.descriptor.java.BasicJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.BooleanJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ClobJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.DoubleJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.InstantJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.IntegerJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.JdbcDateJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.JdbcTimeJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.JdbcTimestampJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ShortJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.StringJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.UrlJavaType;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implNote Limited to H2 simply because some Dialects will map some of these to
|
||||||
|
* minor differences in SQL/JDBC types, and largely such differences are unimportant here
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
@RequiresDialect( H2Dialect.class )
|
||||||
|
public class SpecialTypeTransformationTests {
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry(settings = {
|
||||||
|
@Setting(name = MappingSettings.JAVA_TIME_USE_DIRECT_JDBC, value = "true"),
|
||||||
|
// SqlTypes.INSTANT
|
||||||
|
@Setting(name = MappingSettings.PREFERRED_INSTANT_JDBC_TYPE, value = "3008")
|
||||||
|
} )
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/type/basics.xml")
|
||||||
|
void testBasicsHbmXml(DomainModelScope scope) {
|
||||||
|
scope.withHierarchy( EntityOfBasics.class, this::verify );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry(settings = {
|
||||||
|
@Setting(name = MappingSettings.JAVA_TIME_USE_DIRECT_JDBC, value = "true"),
|
||||||
|
// SqlTypes.INSTANT
|
||||||
|
@Setting(name = MappingSettings.PREFERRED_INSTANT_JDBC_TYPE, value = "3008"),
|
||||||
|
@Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true")
|
||||||
|
} )
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/type/basics.xml")
|
||||||
|
void testBasicsTransformed(DomainModelScope scope) {
|
||||||
|
scope.withHierarchy( EntityOfBasics.class, this::verify );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/type/element-collections.xml")
|
||||||
|
void testElementCollectionsHbmXml(DomainModelScope scope) {
|
||||||
|
scope.withHierarchy( EntityWithElementCollections.class, this::verifyElementCollections );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry(settings = @Setting(name = MappingSettings.TRANSFORM_HBM_XML, value = "true"))
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/type/element-collections.xml")
|
||||||
|
void testElementCollectionsTransformed(DomainModelScope scope) {
|
||||||
|
scope.withHierarchy( EntityWithElementCollections.class, this::verifyElementCollections );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verify(RootClass rootClass) {
|
||||||
|
verify( (BasicType<?>) rootClass.getIdentifier().getType(), IntegerJavaType.class, SqlTypes.INTEGER );
|
||||||
|
verify( rootClass, "theBoolean", BooleanJavaType.class, SqlTypes.BOOLEAN );
|
||||||
|
verify( rootClass, "theString", StringJavaType.class, SqlTypes.VARCHAR );
|
||||||
|
verify( rootClass, "theInt", IntegerJavaType.class, SqlTypes.INTEGER );
|
||||||
|
verify( rootClass, "theInteger", IntegerJavaType.class, SqlTypes.INTEGER );
|
||||||
|
verify( rootClass, "theShort", ShortJavaType.class, SqlTypes.SMALLINT );
|
||||||
|
verify( rootClass, "theDouble", DoubleJavaType.class, SqlTypes.DOUBLE );
|
||||||
|
verify( rootClass, "theUrl", UrlJavaType.class, SqlTypes.VARCHAR );
|
||||||
|
verify( rootClass, "theClob", ClobJavaType.class, SqlTypes.CLOB );
|
||||||
|
verify( rootClass, "theInstant", InstantJavaType.class, SqlTypes.INSTANT );
|
||||||
|
verify( rootClass, "theDate", JdbcDateJavaType.class, SqlTypes.DATE );
|
||||||
|
verify( rootClass, "theTime", JdbcTimeJavaType.class, SqlTypes.TIME );
|
||||||
|
verify( rootClass, "theTimestamp", JdbcTimestampJavaType.class, SqlTypes.TIMESTAMP );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verify(RootClass rootClass, String attributeName, Class<? extends BasicJavaType<?>> expectedJavaType, int expectedJdbcTypeCode) {
|
||||||
|
final Property attribute = rootClass.getProperty( attributeName );
|
||||||
|
assertThat( attribute.getType() ).isInstanceOf( BasicType.class );
|
||||||
|
verify( (BasicType<?>) attribute.getType(), expectedJavaType, expectedJdbcTypeCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyElementCollections(RootClass rootClass) {
|
||||||
|
verifyElementCollection( rootClass, "listOfStrings", StringJavaType.class, SqlTypes.VARCHAR );
|
||||||
|
verifyElementCollection( rootClass, "listOfIntegers", IntegerJavaType.class, SqlTypes.INTEGER );
|
||||||
|
verifyElementCollection( rootClass, "listOfDoubles", DoubleJavaType.class, SqlTypes.DOUBLE );
|
||||||
|
verifyElementCollection( rootClass, "listOfUrls", UrlJavaType.class, SqlTypes.VARCHAR );
|
||||||
|
verifyElementCollection( rootClass, "listOfUuids", UUIDJavaType.class, SqlTypes.OTHER );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyElementCollection(RootClass rootClass, String name, Class<? extends BasicJavaType<?>> expectedJavaType, int expectedJdbcTypeCode) {
|
||||||
|
final Property property = rootClass.getProperty( name );
|
||||||
|
final Collection propertyValue = (Collection) property.getValue();
|
||||||
|
verify( (BasicType<?>) propertyValue.getElement().getType(), expectedJavaType, expectedJdbcTypeCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verify(BasicType<?> type, Class<? extends BasicJavaType<?>> expectedJavaType, int expectedJdbcTypeCode) {
|
||||||
|
assertThat( type.getJavaTypeDescriptor().getClass() ).isEqualTo( expectedJavaType );
|
||||||
|
assertThat( type.getJdbcType().getJdbcTypeCode() ).isEqualTo( expectedJdbcTypeCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,8 +16,6 @@ hibernate.connection.autocommit false
|
||||||
hibernate.connection.initial_pool_size 0
|
hibernate.connection.initial_pool_size 0
|
||||||
hibernate.connection.pool_size 5
|
hibernate.connection.pool_size 5
|
||||||
|
|
||||||
hibernate.transform_hbm_xml.enabled true
|
|
||||||
|
|
||||||
hibernate.show_sql true
|
hibernate.show_sql true
|
||||||
hibernate.format_sql true
|
hibernate.format_sql true
|
||||||
hibernate.highlight_sql true
|
hibernate.highlight_sql true
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping default-access="field">
|
||||||
|
<class name="org.hibernate.testing.orm.domain.gambit.EntityOfBasics">
|
||||||
|
<id type="integer"/>
|
||||||
|
<property name="theBoolean" type="boolean"/>
|
||||||
|
<property name="theString" type="string"/>
|
||||||
|
<property name="theInt" type="int"/>
|
||||||
|
<property name="theInteger" type="integer"/>
|
||||||
|
<property name="theShort" type="java.lang.Short"/>
|
||||||
|
<property name="theDouble" type="double"/>
|
||||||
|
<property name="theUrl" type="url"/>
|
||||||
|
<property name="theClob" type="clob"/>
|
||||||
|
<property name="theInstant" type="instant"/>
|
||||||
|
<property name="theDate" type="date"/>
|
||||||
|
<property name="theTime" type="time"/>
|
||||||
|
<property name="theTimestamp" type="timestamp"/>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping default-access="field">
|
||||||
|
<class name="org.hibernate.orm.test.boot.models.hbm.type.EntityWithElementCollections">
|
||||||
|
<id type="integer"/>
|
||||||
|
<property name="name" type="string"/>
|
||||||
|
|
||||||
|
<list name="listOfStrings">
|
||||||
|
<key column="fk"/>
|
||||||
|
<index column="position"/>
|
||||||
|
<element column="strings" type="string"/>
|
||||||
|
</list>
|
||||||
|
|
||||||
|
<list name="listOfIntegers">
|
||||||
|
<key column="fk"/>
|
||||||
|
<index column="position"/>
|
||||||
|
<element column="numbers" type="integer"/>
|
||||||
|
</list>
|
||||||
|
|
||||||
|
<list name="listOfDoubles">
|
||||||
|
<key column="fk"/>
|
||||||
|
<index column="position"/>
|
||||||
|
<element column="numbers" type="double"/>
|
||||||
|
</list>
|
||||||
|
|
||||||
|
<list name="listOfUrls">
|
||||||
|
<key column="fk"/>
|
||||||
|
<index column="position"/>
|
||||||
|
<element column="numbers" type="url"/>
|
||||||
|
</list>
|
||||||
|
|
||||||
|
<list name="listOfUuids">
|
||||||
|
<key column="fk"/>
|
||||||
|
<index column="position"/>
|
||||||
|
<element column="numbers" type="uuid"/>
|
||||||
|
</list>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
Loading…
Reference in New Issue