Skip to content

Commit

Permalink
#46 - Support <entity/> overrides
Browse files Browse the repository at this point in the history
#47 - Support dynamic <entity/> and <embeddable/> mappings
  • Loading branch information
sebersole committed Oct 23, 2023
1 parent f34a30b commit efe4dea
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -256,18 +256,8 @@ public static MutableMemberDetails processBasicIdAttribute(
sourceModelBuildingContext
);

XmlAnnotationHelper.applyUserType(
jaxbId.getType(),
memberDetails,
sourceModelBuildingContext
);
XmlAnnotationHelper.applyTargetClass(
jaxbId.getTargetClass(),
memberDetails,
sourceModelBuildingContext
);
XmlAnnotationHelper.applyJdbcType(
jaxbId.getJdbcType(),
XmlAnnotationHelper.applyBasicTypeComposition(
jaxbId,
memberDetails,
sourceModelBuildingContext
);
Expand Down Expand Up @@ -359,9 +349,7 @@ public static MutableMemberDetails processBasicAttribute(

XmlAnnotationHelper.applyConvert( jaxbBasic.getConvert(), memberDetails, sourceModelBuildingContext );

XmlAnnotationHelper.applyUserType( jaxbBasic.getType(), memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyTargetClass( jaxbBasic.getTargetClass(), memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyJdbcType( jaxbBasic.getJdbcType(), memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyBasicTypeComposition( jaxbBasic, memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyTemporal( jaxbBasic.getTemporal(), memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyLob( jaxbBasic.getLob(), memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyEnumerated( jaxbBasic.getEnumerated(), memberDetails, sourceModelBuildingContext );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,46 +304,51 @@ private static ClassDetails determineDynamicAttributeJavaType(

if ( jaxbPersistentAttribute instanceof JaxbIdImpl ) {
final JaxbIdImpl jaxbId = (JaxbIdImpl) jaxbPersistentAttribute;
if ( jaxbId.getJavaType() == null || jaxbId.getJavaType().getClazz() == null ) {
return null;
}
else {
return XmlAnnotationHelper.resolveJavaType(
jaxbId.getJavaType().getClazz(),
sourceModelBuildingContext
);
}
return XmlAnnotationHelper.resolveJavaType( jaxbId.getTarget(), sourceModelBuildingContext );
}

if ( jaxbPersistentAttribute instanceof JaxbEmbeddedIdImpl ) {
final JaxbEmbeddedIdImpl jaxbEmbeddedId = (JaxbEmbeddedIdImpl) jaxbPersistentAttribute;
// need target-class here...
throw new UnsupportedOperationException( "Not yet implemented" );
final String target = jaxbEmbeddedId.getEmbeddable();
if ( StringHelper.isEmpty( target ) ) {
return null;
}
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry();
return classDetailsRegistry.resolveClassDetails(
target,
() -> new DynamicClassDetails( target, sourceModelBuildingContext )
);
}

if ( jaxbPersistentAttribute instanceof JaxbBasicImpl ) {
final JaxbBasicImpl jaxbBasic = (JaxbBasicImpl) jaxbPersistentAttribute;
if ( jaxbBasic.getJavaType() == null || jaxbBasic.getJavaType().getClazz() == null ) {
return null;
}
else {
return XmlAnnotationHelper.resolveJavaType(
jaxbBasic.getJavaType().getClazz(),
sourceModelBuildingContext
);
}
return XmlAnnotationHelper.resolveJavaType( jaxbBasic.getTarget(), sourceModelBuildingContext );
}

if ( jaxbPersistentAttribute instanceof JaxbEmbeddedImpl ) {
final JaxbEmbeddedImpl jaxbEmbedded = (JaxbEmbeddedImpl) jaxbPersistentAttribute;
if ( jaxbEmbedded.getEmbeddable() == null ) {
final String target = jaxbEmbedded.getTarget();
if ( StringHelper.isEmpty( target ) ) {
return null;
}
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry();
return classDetailsRegistry.resolveClassDetails(
jaxbEmbedded.getEmbeddable(),
target,
() -> new DynamicClassDetails( target, sourceModelBuildingContext )
);
}

if ( jaxbPersistentAttribute instanceof JaxbOneToOneImpl ) {
final JaxbOneToOneImpl jaxbOneToOne = (JaxbOneToOneImpl) jaxbPersistentAttribute;
final String target = jaxbOneToOne.getTargetEntity();
if ( StringHelper.isEmpty( target ) ) {
return null;
}
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry();
return classDetailsRegistry.resolveClassDetails(
target,
() -> new DynamicClassDetails(
jaxbEmbedded.getEmbeddable(),
target,
null,
false,
null,
Expand All @@ -352,11 +357,6 @@ private static ClassDetails determineDynamicAttributeJavaType(
);
}

if ( jaxbPersistentAttribute instanceof JaxbOneToOneImpl ) {
final JaxbOneToOneImpl jaxbOneToOne = (JaxbOneToOneImpl) jaxbPersistentAttribute;
final String targetEntity = jaxbOneToOne.getTargetEntity();
}

if ( jaxbPersistentAttribute instanceof JaxbAnyMappingImpl ) {
return sourceModelBuildingContext.getClassDetailsRegistry().getClassDetails( Object.class.getName() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.hibernate.models.orm.xml.internal;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
Expand All @@ -15,6 +16,7 @@

import org.hibernate.annotations.AttributeAccessor;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.JavaType;
import org.hibernate.annotations.JdbcType;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.Nationalized;
Expand All @@ -28,6 +30,7 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbAssociationOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributeOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicMapping;
import org.hibernate.boot.jaxb.mapping.spi.JaxbCachingImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbConfigurationParameterImpl;
Expand All @@ -36,17 +39,15 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
import org.hibernate.boot.jaxb.mapping.spi.JaxbGeneratedValueImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJavaTypeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJdbcTypeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLobImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGeneratorImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTableImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbUserTypeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbUuidGeneratorImpl;
import org.hibernate.models.ModelsException;
import org.hibernate.models.internal.CollectionHelper;
import org.hibernate.models.internal.StringHelper;
import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata;
Expand All @@ -60,6 +61,7 @@
import org.hibernate.models.source.spi.ClassDetails;
import org.hibernate.models.source.spi.ClassDetailsRegistry;
import org.hibernate.models.source.spi.SourceModelBuildingContext;
import org.hibernate.type.SqlTypes;

import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
Expand Down Expand Up @@ -287,47 +289,6 @@ public static void applyTargetClass(
targetAnn.setAttributeValue( "value", classDetails );
}

public static void applyJdbcType(
JaxbJdbcTypeImpl jaxbJdbcType,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jaxbJdbcType == null ) {
return;
}

if ( jaxbJdbcType.getCode() != null ) {
applyJdbcTypeCode( jaxbJdbcType.getCode(), memberDetails, sourceModelBuildingContext );
}
else if ( jaxbJdbcType.getDescriptor() != null ) {
applyJdbcTypeDescriptor( jaxbJdbcType.getDescriptor(), memberDetails, sourceModelBuildingContext );
}
}

private static void applyJdbcTypeDescriptor(
String descriptorName,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
final ClassDetails descriptorClassDetails = sourceModelBuildingContext
.getClassDetailsRegistry()
.resolveClassDetails( descriptorName );
final DynamicAnnotationUsage<JdbcType> jdbcTypeAnn = makeAnnotation( JdbcType.class, memberDetails );
jdbcTypeAnn.setAttributeValue( "value", descriptorClassDetails );

}

public static void applyJdbcTypeCode(
Integer jdbcTypeCode,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jdbcTypeCode == null ) {
return;
}

final DynamicAnnotationUsage<JdbcTypeCode> typeCodeAnn = new DynamicAnnotationUsage<>( JdbcTypeCode.class, memberDetails );
memberDetails.addAnnotationUsage( typeCodeAnn );
typeCodeAnn.setAttributeValue( "value", jdbcTypeCode );
}

public static void applyTemporal(
TemporalType temporalType,
MutableMemberDetails memberDetails,
Expand Down Expand Up @@ -717,4 +678,82 @@ else if ( UUID.class.getSimpleName().equals( value ) ) {

return sourceModelBuildingContext.getClassDetailsRegistry().resolveClassDetails( value );
}

public static void applyBasicTypeComposition(
JaxbBasicMapping jaxbBasicMapping,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jaxbBasicMapping.getType() != null ) {
applyUserType( jaxbBasicMapping.getType(), memberDetails, sourceModelBuildingContext );
}
else if ( jaxbBasicMapping.getJavaType() != null ) {
applyJavaTypeDescriptor( jaxbBasicMapping.getJavaType(), memberDetails, sourceModelBuildingContext );
}
else if ( StringHelper.isNotEmpty( jaxbBasicMapping.getTarget() ) ) {
applyTargetClass( jaxbBasicMapping.getTarget(), memberDetails, sourceModelBuildingContext );
}

if ( StringHelper.isNotEmpty( jaxbBasicMapping.getJdbcType() ) ) {
applyJdbcTypeDescriptor( jaxbBasicMapping.getJdbcType(), memberDetails, sourceModelBuildingContext );
}
else if ( jaxbBasicMapping.getJdbcTypeCode() != null ) {
applyJdbcTypeCode( jaxbBasicMapping.getJdbcTypeCode(), memberDetails, sourceModelBuildingContext );
}
else if ( StringHelper.isNotEmpty( jaxbBasicMapping.getJdbcTypeName() ) ) {
applyJdbcTypeCode(
resolveJdbcTypeName( jaxbBasicMapping.getJdbcTypeName() ),
memberDetails,
sourceModelBuildingContext
);
}
}

private static int resolveJdbcTypeName(String name) {
try {
final Field matchingField = SqlTypes.class.getDeclaredField( name );
return matchingField.getInt( null );
}
catch (NoSuchFieldException | IllegalAccessException e) {
throw new ModelsException( "Could not resolve <jdbc-type-name>" + name + "</jdbc-type-name>", e );
}
}

public static void applyJavaTypeDescriptor(
String descriptorClassName,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
final DynamicAnnotationUsage<JavaType> typeAnn = new DynamicAnnotationUsage<>( JavaType.class, memberDetails );
memberDetails.addAnnotationUsage( typeAnn );

final ClassDetails descriptorClass = sourceModelBuildingContext
.getClassDetailsRegistry()
.resolveClassDetails( descriptorClassName );
typeAnn.setAttributeValue( "value", descriptorClass );
}


private static void applyJdbcTypeDescriptor(
String descriptorClassName,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
final ClassDetails descriptorClassDetails = sourceModelBuildingContext
.getClassDetailsRegistry()
.resolveClassDetails( descriptorClassName );
final DynamicAnnotationUsage<JdbcType> jdbcTypeAnn = makeAnnotation( JdbcType.class, memberDetails );
jdbcTypeAnn.setAttributeValue( "value", descriptorClassDetails );

}

public static void applyJdbcTypeCode(
Integer jdbcTypeCode,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jdbcTypeCode == null ) {
return;
}

final DynamicAnnotationUsage<JdbcTypeCode> typeCodeAnn = new DynamicAnnotationUsage<>( JdbcTypeCode.class, memberDetails );
memberDetails.addAnnotationUsage( typeCodeAnn );
typeCodeAnn.setAttributeValue( "value", jdbcTypeCode );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.models.orm.xml.dynamic;

import org.hibernate.annotations.JavaType;
import org.hibernate.models.orm.internal.ManagedResourcesImpl;
import org.hibernate.models.orm.spi.EntityHierarchy;
import org.hibernate.models.orm.spi.EntityTypeMetadata;
Expand Down Expand Up @@ -66,7 +67,8 @@ public boolean shouldIgnoreUnlistedClasses() {
assertThat( idField.getType().getClassName() ).isEqualTo( Integer.class.getName() );

final FieldDetails nameField = rootEntity.getClassDetails().findFieldByName( "name" );
assertThat( nameField.getType().getClassName() ).isEqualTo( String.class.getName() );
assertThat( nameField.getType().getClassName() ).isEqualTo( Object.class.getName() );
assertThat( nameField.getAnnotationUsage( JavaType.class ) ).isNotNull();

final FieldDetails qtyField = rootEntity.getClassDetails().findFieldByName( "quantity" );
assertThat( qtyField.getType().getClassName() ).isEqualTo( int.class.getName() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ public class DynamicClassDetails extends AbstractAnnotationTarget implements Cla

private Class<?> javaType;

public DynamicClassDetails(String name, SourceModelBuildingContext buildingContext) {
this( name, null, buildingContext );
}

public DynamicClassDetails(String name, ClassDetails superType, SourceModelBuildingContext buildingContext) {
this( name, null, false, superType, buildingContext );
}

public DynamicClassDetails(
String name,
String className,
Expand Down

0 comments on commit efe4dea

Please sign in to comment.