HHH-17460 - Ongoing JPA 32 work

This commit is contained in:
Steve Ebersole 2024-04-04 10:26:50 -05:00
parent e9aca835a4
commit 8fe3d9e6aa
12 changed files with 1054 additions and 116 deletions

View File

@ -56,6 +56,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbConvertImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbCustomSqlImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbCustomSqlImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorColumnImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorFormulaImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorFormulaImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity; import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl;
@ -68,10 +69,9 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLifecycleCallback; import org.hibernate.boot.jaxb.mapping.spi.JaxbLifecycleCallback;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLifecycleCallbackContainer; import org.hibernate.boot.jaxb.mapping.spi.JaxbLifecycleCallbackContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLobImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbLobImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId; import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSchemaAware; import org.hibernate.boot.jaxb.mapping.spi.JaxbSchemaAware;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGeneratorImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGeneratorImpl;
@ -111,6 +111,7 @@ import org.hibernate.type.SqlTypes;
import jakarta.persistence.Access; import jakarta.persistence.Access;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import jakarta.persistence.AssociationOverride; import jakarta.persistence.AssociationOverride;
import jakarta.persistence.AssociationOverrides;
import jakarta.persistence.AttributeOverride; import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides; import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.CheckConstraint; import jakarta.persistence.CheckConstraint;
@ -130,8 +131,6 @@ import jakarta.persistence.Index;
import jakarta.persistence.Inheritance; import jakarta.persistence.Inheritance;
import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob; import jakarta.persistence.Lob;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.MapKeyJoinColumn;
import jakarta.persistence.PostLoad; import jakarta.persistence.PostLoad;
import jakarta.persistence.PostPersist; import jakarta.persistence.PostPersist;
import jakarta.persistence.PostRemove; import jakarta.persistence.PostRemove;
@ -376,30 +375,6 @@ public class XmlAnnotationHelper {
applyOr( jaxbCollectionId, JaxbCollectionIdImpl::getGenerator, "generator", collectionIdAnn, collectionIdDescriptor ); applyOr( jaxbCollectionId, JaxbCollectionIdImpl::getGenerator, "generator", collectionIdAnn, collectionIdDescriptor );
} }
public static void applyMapKeyColumn(
JaxbMapKeyColumnImpl jaxbMapKeyColumn,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbMapKeyColumn == null ) {
return;
}
final MutableAnnotationUsage<MapKeyColumn> columnAnn = XmlProcessingHelper.getOrMakeAnnotation( MapKeyColumn.class, memberDetails, xmlDocumentContext );
ColumnProcessing.applyColumnDetails( jaxbMapKeyColumn, memberDetails, columnAnn, xmlDocumentContext );
}
public static void applyMapKeyJoinColumn(
JaxbMapKeyJoinColumnImpl jaxbMapKeyJoinColumn,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbMapKeyJoinColumn == null ) {
return;
}
JoinColumnProcessing.createJoinColumnAnnotation( jaxbMapKeyJoinColumn, memberDetails, MapKeyJoinColumn.class, xmlDocumentContext );
}
public static void applyCascading( public static void applyCascading(
JaxbCascadeTypeImpl jaxbCascadeType, JaxbCascadeTypeImpl jaxbCascadeType,
MutableMemberDetails memberDetails, MutableMemberDetails memberDetails,
@ -663,6 +638,124 @@ public class XmlAnnotationHelper {
annotationUsage.setAttributeValue( "style", jaxbGenerator.getStyle() ); annotationUsage.setAttributeValue( "style", jaxbGenerator.getStyle() );
} }
public static void applyAttributeOverrides(
JaxbPluralAttribute pluralAttribute,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
final List<JaxbAttributeOverrideImpl> jaxbMapKeyOverrides = pluralAttribute.getMapKeyAttributeOverrides();
final List<JaxbAttributeOverrideImpl> jaxbElementOverrides = pluralAttribute instanceof JaxbElementCollectionImpl
? ( (JaxbElementCollectionImpl) pluralAttribute ).getAttributeOverrides()
: emptyList();
if ( CollectionHelper.isEmpty( jaxbMapKeyOverrides ) && CollectionHelper.isEmpty( jaxbElementOverrides ) ) {
return;
}
final int numberOfOverrides = jaxbMapKeyOverrides.size() + jaxbElementOverrides.size();
if ( numberOfOverrides == 1 ) {
final MutableAnnotationUsage<AttributeOverride> overrideUsage;
if ( memberDetails.getMapKeyType() != null ) {
if ( jaxbMapKeyOverrides.size() == 1 ) {
overrideUsage = createAttributeOverrideUsage(
jaxbMapKeyOverrides.get( 0 ),
"key",
memberDetails,
xmlDocumentContext
);
}
else {
assert jaxbElementOverrides.size() == 1;
overrideUsage = createAttributeOverrideUsage(
jaxbElementOverrides.get( 0 ),
"value",
memberDetails,
xmlDocumentContext
);
}
}
else {
assert jaxbElementOverrides.size() == 1;
overrideUsage = createAttributeOverrideUsage(
jaxbElementOverrides.get( 0 ),
null,
memberDetails,
xmlDocumentContext
);
}
memberDetails.addAnnotationUsage( overrideUsage );
return;
}
final SourceModelBuildingContext modelBuildingContext = xmlDocumentContext.getModelBuildingContext();
final MutableAnnotationUsage<AttributeOverrides> overridesUsage = JpaAnnotations.ATTRIBUTE_OVERRIDES.createUsage(
memberDetails,
modelBuildingContext
);
memberDetails.addAnnotationUsage( overridesUsage );
final List<MutableAnnotationUsage<AttributeOverride>> overrideUsages = CollectionHelper.arrayList(
numberOfOverrides
);
overridesUsage.setAttributeValue( "value", overrideUsages );
// We need to handle overrides for maps specially...
if ( memberDetails.getMapKeyType() != null ) {
jaxbMapKeyOverrides.forEach( (jaxbOverride) -> {
overrideUsages.add( createAttributeOverrideUsage(
jaxbOverride,
"key",
memberDetails,
xmlDocumentContext
) );
} );
jaxbElementOverrides.forEach( (jaxbOverride) -> {
overrideUsages.add( createAttributeOverrideUsage(
jaxbOverride,
"value",
memberDetails,
xmlDocumentContext
) );
} );
}
else {
assert CollectionHelper.isEmpty( jaxbMapKeyOverrides );
jaxbElementOverrides.forEach( (jaxbOverride) -> {
overrideUsages.add( createAttributeOverrideUsage(
jaxbOverride,
null,
memberDetails,
xmlDocumentContext
) );
} );
}
}
private static MutableAnnotationUsage<AttributeOverride> createAttributeOverrideUsage(
JaxbAttributeOverrideImpl jaxbOverride,
String namePrefix,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
final SourceModelBuildingContext modelBuildingContext = xmlDocumentContext.getModelBuildingContext();
final MutableAnnotationUsage<AttributeOverride> overrideUsage = JpaAnnotations.ATTRIBUTE_OVERRIDE.createUsage(
memberDetails,
modelBuildingContext
);
final String name = StringHelper.qualifyConditionally( namePrefix, jaxbOverride.getName() );
overrideUsage.setAttributeValue( "name", name );
final MutableAnnotationUsage<Column> columnAnn = JpaAnnotations.COLUMN.createUsage(
memberDetails,
modelBuildingContext
);
overrideUsage.setAttributeValue( "column", columnAnn );
ColumnProcessing.applyColumnDetails( jaxbOverride.getColumn(), memberDetails, columnAnn, xmlDocumentContext );
return overrideUsage;
}
public static void applyAttributeOverrides( public static void applyAttributeOverrides(
List<JaxbAttributeOverrideImpl> jaxbOverrides, List<JaxbAttributeOverrideImpl> jaxbOverrides,
MutableMemberDetails memberDetails, MutableMemberDetails memberDetails,
@ -686,26 +779,16 @@ public class XmlAnnotationHelper {
); );
memberDetails.addAnnotationUsage( attributeOverridesAnn ); memberDetails.addAnnotationUsage( attributeOverridesAnn );
final ArrayList<MutableAnnotationUsage<AttributeOverride>> overrideAnnList = CollectionHelper.arrayList( jaxbOverrides.size() ); final ArrayList<MutableAnnotationUsage<AttributeOverride>> overrideUsages = CollectionHelper.arrayList( jaxbOverrides.size() );
attributeOverridesAnn.setAttributeValue( "value", overrideAnnList ); attributeOverridesAnn.setAttributeValue( "value", overrideUsages );
jaxbOverrides.forEach( (jaxbOverride) -> { jaxbOverrides.forEach( (jaxbOverride) -> {
final MutableAnnotationUsage<AttributeOverride> attributeOverrideAnn = XmlProcessingHelper.makeNestedAnnotation( overrideUsages.add( createAttributeOverrideUsage(
AttributeOverride.class, jaxbOverride,
namePrefix,
memberDetails, memberDetails,
xmlDocumentContext xmlDocumentContext
); ) );
overrideAnnList.add( attributeOverrideAnn );
attributeOverrideAnn.setAttributeValue( "name", prefixIfNotAlready( jaxbOverride.getName(), namePrefix ) );
final MutableAnnotationUsage<Column> columnAnn = makeNestedAnnotation(
Column.class,
memberDetails,
xmlDocumentContext
);
attributeOverrideAnn.setAttributeValue( "column", columnAnn );
ColumnProcessing.applyColumnDetails( jaxbOverride.getColumn(), memberDetails, columnAnn, xmlDocumentContext );
} ); } );
} }
@ -717,31 +800,64 @@ public class XmlAnnotationHelper {
return; return;
} }
jaxbOverrides.forEach( (jaxbOverride) -> { if ( jaxbOverrides.size() == 1 ) {
final MutableAnnotationUsage<AssociationOverride> annotationUsage = XmlProcessingHelper.makeAnnotation( final MutableAnnotationUsage<AssociationOverride> overrideUsage = memberDetails.applyAnnotationUsage(
AssociationOverride.class, JpaAnnotations.ASSOCIATION_OVERRIDE,
xmlDocumentContext.getModelBuildingContext()
);
transferAssociationOverride(
jaxbOverrides.get( 0 ),
overrideUsage,
memberDetails, memberDetails,
xmlDocumentContext xmlDocumentContext
); );
memberDetails.addAnnotationUsage( annotationUsage ); }
XmlProcessingHelper.applyAttributeIfSpecified( "name", jaxbOverride.getName(), annotationUsage ); else {
final List<JaxbJoinColumnImpl> joinColumns = jaxbOverride.getJoinColumns(); final MutableAnnotationUsage<AssociationOverrides> overridesUsage = memberDetails.applyAnnotationUsage(
if ( CollectionHelper.isNotEmpty( joinColumns ) ) { JpaAnnotations.ASSOCIATION_OVERRIDES,
annotationUsage.setAttributeValue( "joinColumns", JoinColumnProcessing.createJoinColumns( joinColumns, memberDetails, xmlDocumentContext ) ); xmlDocumentContext.getModelBuildingContext()
} );
if ( jaxbOverride.getJoinTable() != null ) { final ArrayList<MutableAnnotationUsage<AssociationOverride>> overrideUsages = CollectionHelper.arrayList( jaxbOverrides.size() );
annotationUsage.setAttributeValue( overridesUsage.setAttributeValue( "value", overrideUsages );
"joinTable",
TableProcessing.applyJoinTable( jaxbOverride.getJoinTable(), memberDetails, xmlDocumentContext ) jaxbOverrides.forEach( (jaxbOverride) -> {
final MutableAnnotationUsage<AssociationOverride> overrideUsage = JpaAnnotations.ASSOCIATION_OVERRIDE.createUsage(
memberDetails,
xmlDocumentContext.getModelBuildingContext()
); );
} transferAssociationOverride( jaxbOverride, overrideUsage, memberDetails, xmlDocumentContext );
if ( jaxbOverride.getForeignKeys() != null ) { overrideUsages.add( overrideUsage );
annotationUsage.setAttributeValue( } );
"foreignKey", }
ForeignKeyProcessing.createForeignKeyAnnotation( jaxbOverride.getForeignKeys(), memberDetails, xmlDocumentContext ) }
);
} private static void transferAssociationOverride(
} ); JaxbAssociationOverrideImpl jaxbOverride,
MutableAnnotationUsage<AssociationOverride> overrideUsage,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
overrideUsage.setAttributeValue( "name", jaxbOverride.getName() );
final List<JaxbJoinColumnImpl> joinColumns = jaxbOverride.getJoinColumns();
if ( CollectionHelper.isNotEmpty( joinColumns ) ) {
overrideUsage.setAttributeValue(
"joinColumns",
JoinColumnProcessing.transformJoinColumnList( joinColumns, memberDetails, xmlDocumentContext )
);
}
if ( jaxbOverride.getJoinTable() != null ) {
overrideUsage.setAttributeValue(
"joinTable",
TableProcessing.transformJoinTable( jaxbOverride.getJoinTable(), memberDetails, xmlDocumentContext )
);
}
if ( jaxbOverride.getForeignKeys() != null ) {
overrideUsage.setAttributeValue(
"foreignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbOverride.getForeignKeys(), memberDetails, xmlDocumentContext )
);
}
} }
public static void applyOptimisticLockInclusion( public static void applyOptimisticLockInclusion(

View File

@ -21,7 +21,9 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbOrderColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute; import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
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.internal.db.ColumnProcessing;
import org.hibernate.boot.models.xml.internal.db.ForeignKeyProcessing; import org.hibernate.boot.models.xml.internal.db.ForeignKeyProcessing;
import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
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.internal.util.StringHelper;
import org.hibernate.models.spi.AnnotationDescriptor; import org.hibernate.models.spi.AnnotationDescriptor;
@ -115,7 +117,8 @@ public class CommonPluralAttributeProcessing {
} }
if ( jaxbPluralAttribute.getMapKeyClass() != null ) { if ( jaxbPluralAttribute.getMapKeyClass() != null ) {
final ClassDetails mapKeyClass = classDetailsRegistry.resolveClassDetails( jaxbPluralAttribute.getMapKeyClass().getClazz() ); final String className = xmlDocumentContext.resolveClassName( jaxbPluralAttribute.getMapKeyClass().getClazz() );
final ClassDetails mapKeyClass = classDetailsRegistry.resolveClassDetails( className );
XmlProcessingHelper.getOrMakeAnnotation( MapKeyClass.class, memberDetails, xmlDocumentContext ).setAttributeValue( "value", mapKeyClass ); XmlProcessingHelper.getOrMakeAnnotation( MapKeyClass.class, memberDetails, xmlDocumentContext ).setAttributeValue( "value", mapKeyClass );
} }
@ -133,22 +136,17 @@ public class CommonPluralAttributeProcessing {
); );
} }
XmlAnnotationHelper.applyAttributeOverrides(
jaxbPluralAttribute.getMapKeyAttributeOverrides(),
memberDetails,
"key",
xmlDocumentContext
);
jaxbPluralAttribute.getMapKeyConverts().forEach( (jaxbConvert) -> { jaxbPluralAttribute.getMapKeyConverts().forEach( (jaxbConvert) -> {
XmlAnnotationHelper.applyConvert( jaxbConvert, memberDetails, "key", xmlDocumentContext ); XmlAnnotationHelper.applyConvert( jaxbConvert, memberDetails, "key", xmlDocumentContext );
} ); } );
XmlAnnotationHelper.applyMapKeyColumn( jaxbPluralAttribute.getMapKeyColumn(), memberDetails, xmlDocumentContext ); ColumnProcessing.applyMapKeyColumn( jaxbPluralAttribute.getMapKeyColumn(), memberDetails, xmlDocumentContext );
jaxbPluralAttribute.getMapKeyJoinColumns().forEach( jaxbMapKeyJoinColumn -> { JoinColumnProcessing.applyMapKeyJoinColumns(
XmlAnnotationHelper.applyMapKeyJoinColumn( jaxbMapKeyJoinColumn, memberDetails, xmlDocumentContext ); jaxbPluralAttribute.getMapKeyJoinColumns(),
} ); memberDetails,
xmlDocumentContext
);
ForeignKeyProcessing.applyForeignKey( jaxbPluralAttribute.getMapKeyForeignKey(), memberDetails, xmlDocumentContext ); ForeignKeyProcessing.applyForeignKey( jaxbPluralAttribute.getMapKeyForeignKey(), memberDetails, xmlDocumentContext );

View File

@ -6,8 +6,11 @@
*/ */
package org.hibernate.boot.models.xml.internal.attr; package org.hibernate.boot.models.xml.internal.attr;
import org.hibernate.boot.internal.Target;
import org.hibernate.boot.jaxb.mapping.spi.JaxbCollectionTableImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbCollectionTableImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
import org.hibernate.boot.models.HibernateAnnotations;
import org.hibernate.boot.models.JpaAnnotations;
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.internal.db.ForeignKeyProcessing; import org.hibernate.boot.models.xml.internal.db.ForeignKeyProcessing;
@ -42,32 +45,32 @@ public class ElementCollectionAttributeProcessing {
declarer declarer
); );
final MutableAnnotationUsage<ElementCollection> elementCollectionAnn = XmlProcessingHelper.getOrMakeAnnotation( final MutableAnnotationUsage<ElementCollection> elementCollectionUsage = memberDetails.applyAnnotationUsage(
ElementCollection.class, JpaAnnotations.ELEMENT_COLLECTION,
memberDetails, xmlDocumentContext.getModelBuildingContext()
xmlDocumentContext
); );
XmlProcessingHelper.applyAttributeIfSpecified( XmlProcessingHelper.applyAttributeIfSpecified(
"fetch", "fetch",
jaxbElementCollection.getFetch(), jaxbElementCollection.getFetch(),
elementCollectionAnn elementCollectionUsage
); );
final String targetClass = jaxbElementCollection.getTargetClass(); final String targetClass = jaxbElementCollection.getTargetClass();
if ( targetClass != null ) { if ( targetClass != null ) {
XmlProcessingHelper.applyAttributeIfSpecified( final MutableAnnotationUsage<Target> targetUsage = memberDetails.applyAnnotationUsage(
"targetClass", HibernateAnnotations.TARGET,
XmlAnnotationHelper.resolveJavaType( targetClass, xmlDocumentContext.getModelBuildingContext() ).determineRawClass(), xmlDocumentContext.getModelBuildingContext()
elementCollectionAnn
); );
targetUsage.setAttributeValue( "value", xmlDocumentContext.resolveClassName( targetClass ) );
} }
CommonAttributeProcessing.applyAttributeBasics( jaxbElementCollection, memberDetails, elementCollectionAnn, accessType, xmlDocumentContext ); CommonAttributeProcessing.applyAttributeBasics( jaxbElementCollection, memberDetails, elementCollectionUsage, accessType, xmlDocumentContext );
CommonPluralAttributeProcessing.applyPluralAttributeStructure( jaxbElementCollection, memberDetails, xmlDocumentContext ); CommonPluralAttributeProcessing.applyPluralAttributeStructure( jaxbElementCollection, memberDetails, xmlDocumentContext );
applyCollectionTable( jaxbElementCollection.getCollectionTable(), memberDetails, xmlDocumentContext ); applyCollectionTable( jaxbElementCollection.getCollectionTable(), memberDetails, xmlDocumentContext );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// elements // elements
@ -78,12 +81,13 @@ public class ElementCollectionAttributeProcessing {
XmlAnnotationHelper.applyTemporal( jaxbElementCollection.getTemporal(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyTemporal( jaxbElementCollection.getTemporal(), memberDetails, xmlDocumentContext );
XmlAnnotationHelper.applyBasicTypeComposition( jaxbElementCollection, memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyBasicTypeComposition( jaxbElementCollection, memberDetails, xmlDocumentContext );
jaxbElementCollection.getConverts().forEach( (jaxbConvert) -> { jaxbElementCollection.getConverts().forEach( (jaxbConvert) -> XmlAnnotationHelper.applyConvert(
XmlAnnotationHelper.applyConvert( jaxbConvert, memberDetails, xmlDocumentContext ); jaxbConvert,
} ); memberDetails,
xmlDocumentContext
XmlAnnotationHelper.applyAttributeOverrides( jaxbElementCollection.getAttributeOverrides(), memberDetails, xmlDocumentContext ); ) );
XmlAnnotationHelper.applyAttributeOverrides( jaxbElementCollection, memberDetails, xmlDocumentContext );
XmlAnnotationHelper.applyAssociationOverrides( jaxbElementCollection.getAssociationOverrides(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyAssociationOverrides( jaxbElementCollection.getAssociationOverrides(), memberDetails, xmlDocumentContext );
return memberDetails; return memberDetails;
@ -122,7 +126,11 @@ public class ElementCollectionAttributeProcessing {
); );
XmlAnnotationHelper.applyOr( jaxbCollectionTable, JaxbCollectionTableImpl::getOptions, "options", collectionTableAnn, collectionTableDescriptor ); XmlAnnotationHelper.applyOr( jaxbCollectionTable, JaxbCollectionTableImpl::getOptions, "options", collectionTableAnn, collectionTableDescriptor );
collectionTableAnn.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList( jaxbCollectionTable.getJoinColumns(), xmlDocumentContext ) ); collectionTableAnn.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList(
jaxbCollectionTable.getJoinColumns(),
memberDetails,
xmlDocumentContext
) );
if ( jaxbCollectionTable.getForeignKeys() != null ) { if ( jaxbCollectionTable.getForeignKeys() != null ) {
collectionTableAnn.setAttributeValue( collectionTableAnn.setAttributeValue(

View File

@ -52,10 +52,16 @@ public class ManyToManyAttributeProcessing {
XmlAnnotationHelper.applyCascading( jaxbManyToMany.getCascade(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyCascading( jaxbManyToMany.getCascade(), memberDetails, xmlDocumentContext );
CommonAttributeProcessing.applyAttributeBasics( jaxbManyToMany, memberDetails, manyToManyAnn, accessType, xmlDocumentContext ); CommonAttributeProcessing.applyAttributeBasics( jaxbManyToMany, memberDetails, manyToManyAnn, accessType, xmlDocumentContext );
CommonPluralAttributeProcessing.applyPluralAttributeStructure( jaxbManyToMany, memberDetails, xmlDocumentContext ); CommonPluralAttributeProcessing.applyPluralAttributeStructure( jaxbManyToMany, memberDetails, xmlDocumentContext );
TableProcessing.applyJoinTable( jaxbManyToMany.getJoinTable(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyAttributeOverrides(
jaxbManyToMany.getMapKeyAttributeOverrides(),
memberDetails,
"key",
xmlDocumentContext
);
TableProcessing.transformJoinTable( jaxbManyToMany.getJoinTable(), memberDetails, xmlDocumentContext );
XmlAnnotationHelper.applySqlJoinTableRestriction( jaxbManyToMany.getSqlJoinTableRestriction(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applySqlJoinTableRestriction( jaxbManyToMany.getSqlJoinTableRestriction(), memberDetails, xmlDocumentContext );

View File

@ -59,7 +59,7 @@ public class ManyToOneAttributeProcessing {
CommonAttributeProcessing.applyAttributeBasics( jaxbManyToOne, memberDetails, manyToOneAnn, accessType, xmlDocumentContext ); CommonAttributeProcessing.applyAttributeBasics( jaxbManyToOne, memberDetails, manyToOneAnn, accessType, xmlDocumentContext );
TableProcessing.applyJoinTable( jaxbManyToOne.getJoinTable(), memberDetails, xmlDocumentContext ); TableProcessing.transformJoinTable( jaxbManyToOne.getJoinTable(), memberDetails, xmlDocumentContext );
JoinColumnProcessing.applyJoinColumns( jaxbManyToOne.getJoinColumns(), memberDetails, xmlDocumentContext ); JoinColumnProcessing.applyJoinColumns( jaxbManyToOne.getJoinColumns(), memberDetails, xmlDocumentContext );
applyNotFound( memberDetails, jaxbManyToOne, manyToOneAnn, xmlDocumentContext ); applyNotFound( memberDetails, jaxbManyToOne, manyToOneAnn, xmlDocumentContext );

View File

@ -53,10 +53,17 @@ public class OneToManyAttributeProcessing {
CommonPluralAttributeProcessing.applyPluralAttributeStructure( jaxbOneToMany, memberDetails, xmlDocumentContext ); CommonPluralAttributeProcessing.applyPluralAttributeStructure( jaxbOneToMany, memberDetails, xmlDocumentContext );
XmlAnnotationHelper.applyCascading( jaxbOneToMany.getCascade(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyCascading( jaxbOneToMany.getCascade(), memberDetails, xmlDocumentContext );
XmlAnnotationHelper.applyAttributeOverrides(
jaxbOneToMany.getMapKeyAttributeOverrides(),
memberDetails,
"key",
xmlDocumentContext
);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// join-table // join-table
TableProcessing.applyJoinTable( jaxbOneToMany.getJoinTable(), memberDetails, xmlDocumentContext ); TableProcessing.transformJoinTable( jaxbOneToMany.getJoinTable(), memberDetails, xmlDocumentContext );
XmlAnnotationHelper.applySqlJoinTableRestriction( jaxbOneToMany.getSqlJoinTableRestriction(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applySqlJoinTableRestriction( jaxbOneToMany.getSqlJoinTableRestriction(), memberDetails, xmlDocumentContext );

View File

@ -55,7 +55,7 @@ public class OneToOneAttributeProcessing {
applyTarget( memberDetails, jaxbOneToOne, oneToOneAnn, xmlDocumentContext ); applyTarget( memberDetails, jaxbOneToOne, oneToOneAnn, xmlDocumentContext );
applyCascading( jaxbOneToOne.getCascade(), memberDetails, xmlDocumentContext ); applyCascading( jaxbOneToOne.getCascade(), memberDetails, xmlDocumentContext );
TableProcessing.applyJoinTable( jaxbOneToOne.getJoinTable(), memberDetails, xmlDocumentContext ); TableProcessing.transformJoinTable( jaxbOneToOne.getJoinTable(), memberDetails, xmlDocumentContext );
JoinColumnProcessing.applyJoinColumns( jaxbOneToOne.getJoinColumn(), memberDetails, xmlDocumentContext ); JoinColumnProcessing.applyJoinColumns( jaxbOneToOne.getJoinColumn(), memberDetails, xmlDocumentContext );
JoinColumnProcessing.applyPrimaryKeyJoinColumns( jaxbOneToOne.getPrimaryKeyJoinColumn(), memberDetails, xmlDocumentContext ); JoinColumnProcessing.applyPrimaryKeyJoinColumns( jaxbOneToOne.getPrimaryKeyJoinColumn(), memberDetails, xmlDocumentContext );

View File

@ -8,6 +8,7 @@ package org.hibernate.boot.models.xml.internal.db;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.db.JaxbCheckable; import org.hibernate.boot.jaxb.mapping.spi.db.JaxbCheckable;
import org.hibernate.boot.jaxb.mapping.spi.db.JaxbColumn; import org.hibernate.boot.jaxb.mapping.spi.db.JaxbColumn;
import org.hibernate.boot.jaxb.mapping.spi.db.JaxbColumnCommon; import org.hibernate.boot.jaxb.mapping.spi.db.JaxbColumnCommon;
@ -24,6 +25,9 @@ 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.models.spi.MutableAnnotationTarget; import org.hibernate.models.spi.MutableAnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationUsage; import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails;
import jakarta.persistence.MapKeyColumn;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -194,4 +198,17 @@ public class ColumnProcessing {
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
XmlProcessingHelper.applyAttributeIfSpecified( "comment", jaxbColumn.getComment(), columnAnn ); XmlProcessingHelper.applyAttributeIfSpecified( "comment", jaxbColumn.getComment(), columnAnn );
} }
public static void applyMapKeyColumn(
JaxbMapKeyColumnImpl jaxbMapKeyColumn,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbMapKeyColumn == null ) {
return;
}
final MutableAnnotationUsage<MapKeyColumn> columnAnn = XmlProcessingHelper.getOrMakeAnnotation( MapKeyColumn.class, memberDetails, xmlDocumentContext );
applyColumnDetails( jaxbMapKeyColumn, memberDetails, columnAnn, xmlDocumentContext );
}
} }

View File

@ -13,6 +13,7 @@ import java.util.List;
import org.hibernate.boot.jaxb.mapping.spi.JaxbForeignKeyImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbForeignKeyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPrimaryKeyJoinColumnImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbPrimaryKeyJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.db.JaxbColumnJoined; import org.hibernate.boot.jaxb.mapping.spi.db.JaxbColumnJoined;
import org.hibernate.boot.models.JpaAnnotations; import org.hibernate.boot.models.JpaAnnotations;
@ -28,15 +29,55 @@ import jakarta.persistence.CollectionTable;
import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinColumns; import jakarta.persistence.JoinColumns;
import jakarta.persistence.JoinTable; import jakarta.persistence.JoinTable;
import jakarta.persistence.MapKeyJoinColumn;
import jakarta.persistence.MapKeyJoinColumns;
import jakarta.persistence.PrimaryKeyJoinColumn; import jakarta.persistence.PrimaryKeyJoinColumn;
import jakarta.persistence.PrimaryKeyJoinColumns; import jakarta.persistence.PrimaryKeyJoinColumns;
/** /**
* XML -> AnnotationUsage support for {@linkplain JaxbColumnJoined} * XML -> AnnotationUsage support for {@linkplain JaxbColumnJoined}: <ul>
* <li>{@code <join-column/>}</li>
* <li>{@code <primary-key-join-column/>}</li>
* <li>{@code <map-key-join-column/>}</li>
* </ul>
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JoinColumnProcessing { public class JoinColumnProcessing {
public static void applyMapKeyJoinColumns(
List<JaxbMapKeyJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return;
}
if ( jaxbJoinColumns.size() == 1 ) {
final MutableAnnotationUsage<MapKeyJoinColumn> joinColumnUsage = memberDetails.applyAnnotationUsage(
JpaAnnotations.MAP_KEY_JOIN_COLUMN,
xmlDocumentContext.getModelBuildingContext()
);
transferJoinColumn( jaxbJoinColumns.get( 0 ), joinColumnUsage, memberDetails, xmlDocumentContext );
}
else {
final MutableAnnotationUsage<MapKeyJoinColumns> joinColumnsUsage = memberDetails.applyAnnotationUsage(
JpaAnnotations.MAP_KEY_JOIN_COLUMNS,
xmlDocumentContext.getModelBuildingContext()
);
final ArrayList<MutableAnnotationUsage<MapKeyJoinColumn>> joinColumnUsages = CollectionHelper.arrayList( jaxbJoinColumns.size() );
joinColumnsUsage.setAttributeValue( "value", joinColumnUsages );
jaxbJoinColumns.forEach( (jaxbJoinColumn) -> {
final MutableAnnotationUsage<MapKeyJoinColumn> joinColumnUsage = JpaAnnotations.MAP_KEY_JOIN_COLUMN.createUsage(
memberDetails,
xmlDocumentContext.getModelBuildingContext()
);
joinColumnUsages.add( joinColumnUsage );
transferJoinColumn( jaxbJoinColumn, joinColumnUsage, memberDetails, xmlDocumentContext );
} );
}
}
/** /**
* Support for {@linkplain JaxbPrimaryKeyJoinColumnImpl} to {@linkplain PrimaryKeyJoinColumns} transformation * Support for {@linkplain JaxbPrimaryKeyJoinColumnImpl} to {@linkplain PrimaryKeyJoinColumns} transformation
* *
@ -73,7 +114,7 @@ public class JoinColumnProcessing {
} ); } );
} }
private static void transferJoinColumn( public static void transferJoinColumn(
JaxbColumnJoined jaxbJoinColumn, JaxbColumnJoined jaxbJoinColumn,
MutableAnnotationUsage<? extends Annotation> joinColumnUsage, MutableAnnotationUsage<? extends Annotation> joinColumnUsage,
MutableMemberDetails memberDetails, MutableMemberDetails memberDetails,
@ -102,13 +143,19 @@ public class JoinColumnProcessing {
*/ */
public static List<AnnotationUsage<JoinColumn>> transformJoinColumnList( public static List<AnnotationUsage<JoinColumn>> transformJoinColumnList(
List<JaxbJoinColumnImpl> jaxbJoinColumns, List<JaxbJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) { if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return Collections.emptyList(); return Collections.emptyList();
} }
final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() ); final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() );
jaxbJoinColumns.forEach( jaxbJoinColumn -> { jaxbJoinColumns.forEach( jaxbJoinColumn -> {
joinColumns.add( createJoinColumnAnnotation( jaxbJoinColumn, JoinColumn.class, xmlDocumentContext ) ); final MutableAnnotationUsage<JoinColumn> joinColumnAnn = JpaAnnotations.JOIN_COLUMN.createUsage(
memberDetails,
xmlDocumentContext.getModelBuildingContext()
);
transferJoinColumn( jaxbJoinColumn, joinColumnAnn, null, xmlDocumentContext );
joinColumns.add( joinColumnAnn );
} ); } );
return joinColumns; return joinColumns;
} }
@ -128,15 +175,6 @@ public class JoinColumnProcessing {
return joinColumnAnn; return joinColumnAnn;
} }
public static <A extends Annotation> MutableAnnotationUsage<A> createJoinColumnAnnotation(
JaxbColumnJoined jaxbJoinColumn,
Class<A> annotationType,
XmlDocumentContext xmlDocumentContext) {
final MutableAnnotationUsage<A> joinColumnAnn = XmlProcessingHelper.getOrMakeAnnotation( annotationType, xmlDocumentContext );
transferJoinColumn( jaxbJoinColumn, joinColumnAnn, null, xmlDocumentContext );
return joinColumnAnn;
}
public static List<AnnotationUsage<JoinColumn>> createJoinColumns( public static List<AnnotationUsage<JoinColumn>> createJoinColumns(
List<JaxbJoinColumnImpl> jaxbJoinColumns, List<JaxbJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails, MutableMemberDetails memberDetails,

View File

@ -23,7 +23,7 @@ import jakarta.persistence.JoinTable;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class TableProcessing { public class TableProcessing {
public static MutableAnnotationUsage<JoinTable> applyJoinTable( public static MutableAnnotationUsage<JoinTable> transformJoinTable(
JaxbJoinTableImpl jaxbJoinTable, JaxbJoinTableImpl jaxbJoinTable,
MutableMemberDetails memberDetails, MutableMemberDetails memberDetails,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
@ -41,12 +41,19 @@ public class TableProcessing {
final List<JaxbJoinColumnImpl> joinColumns = jaxbJoinTable.getJoinColumn(); final List<JaxbJoinColumnImpl> joinColumns = jaxbJoinTable.getJoinColumn();
if ( CollectionHelper.isNotEmpty( joinColumns ) ) { if ( CollectionHelper.isNotEmpty( joinColumns ) ) {
joinTableUsage.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList( joinColumns, xmlDocumentContext ) ); joinTableUsage.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList(
joinColumns,
memberDetails,
xmlDocumentContext
) );
} }
final List<JaxbJoinColumnImpl> inverseJoinColumns = jaxbJoinTable.getInverseJoinColumn(); final List<JaxbJoinColumnImpl> inverseJoinColumns = jaxbJoinTable.getInverseJoinColumn();
if ( CollectionHelper.isNotEmpty( inverseJoinColumns ) ) { if ( CollectionHelper.isNotEmpty( inverseJoinColumns ) ) {
joinTableUsage.setAttributeValue( "inverseJoinColumns", JoinColumnProcessing.transformJoinColumnList( inverseJoinColumns, xmlDocumentContext ) ); joinTableUsage.setAttributeValue( "inverseJoinColumns", JoinColumnProcessing.transformJoinColumnList(
inverseJoinColumns,
memberDetails,
xmlDocumentContext
) );
} }
if ( jaxbJoinTable.getForeignKey() != null ) { if ( jaxbJoinTable.getForeignKey() != null ) {

View File

@ -0,0 +1,734 @@
/*
* 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.annotations.xml.ejb3;
import java.lang.annotation.Annotation;
import java.util.List;
import org.hibernate.boot.internal.Target;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.MemberDetails;
import org.hibernate.testing.orm.junit.JiraKey;
import org.junit.Test;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.AssociationOverride;
import jakarta.persistence.AssociationOverrides;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinColumns;
import jakarta.persistence.Lob;
import jakarta.persistence.MapKey;
import jakarta.persistence.MapKeyClass;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.MapKeyEnumerated;
import jakarta.persistence.MapKeyJoinColumn;
import jakarta.persistence.MapKeyJoinColumns;
import jakarta.persistence.MapKeyTemporal;
import jakarta.persistence.OrderBy;
import jakarta.persistence.OrderColumn;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.persistence.UniqueConstraint;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("deprecation")
@JiraKey("HHH-14529")
public class Ejb3XmlElementCollectionTest extends Ejb3XmlTestCase {
@Test
public void testNoChildren() {
final MemberDetails memberDetails = getAttributeMember( Entity2.class, "field1", "element-collection.orm1.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderBy.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( OrderColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( Column.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( Temporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( Enumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( Lob.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverrides.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverride.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AssociationOverride.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AssociationOverrides.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( CollectionTable.class ) ).isFalse();
final AnnotationUsage<ElementCollection> elementCollectionUsage = memberDetails.getAnnotationUsage( ElementCollection.class );
assertThat( elementCollectionUsage.getEnum( "fetch", FetchType.class ) ).isEqualTo( FetchType.LAZY );
assertThat( elementCollectionUsage.getClassDetails( "targetClass" ) ).isEqualTo( ClassDetails.VOID_CLASS_DETAILS );
}
@Test
public void testOrderBy() {
final MemberDetails memberDetails = getAttributeMember( Entity2.class, "field1", "element-collection.orm2.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderBy.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderColumn.class ) ).isFalse();
final AnnotationUsage<OrderBy> orderByUsage = memberDetails.getAnnotationUsage( OrderBy.class );
assertThat( orderByUsage.getString( "value" ) ).isEqualTo( "col1 ASC, col2 DESC" );
}
@Test
public void testOrderColumnNoAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity2.class, "field1", "element-collection.orm3.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderColumn.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderBy.class ) ).isFalse();
final AnnotationUsage<OrderColumn> orderColumnUsage = memberDetails.getAnnotationUsage( OrderColumn.class );
assertThat( orderColumnUsage.getString( "name" ) ).isEmpty();
assertThat( orderColumnUsage.getString( "columnDefinition" ) ).isEmpty();
assertThat( orderColumnUsage.getBoolean( "insertable" ) ).isTrue();
assertThat( orderColumnUsage.getBoolean( "updatable" ) ).isTrue();
assertThat( orderColumnUsage.getBoolean( "nullable" ) ).isTrue();
}
@Test
public void testOrderColumnAllAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity2.class, "field1", "element-collection.orm4.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderColumn.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( OrderBy.class ) ).isFalse();
final AnnotationUsage<OrderColumn> orderColumnUsage = memberDetails.getAnnotationUsage( OrderColumn.class );
assertThat( orderColumnUsage.getString( "name" ) ).isEqualTo( "col1" );
assertThat( orderColumnUsage.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( orderColumnUsage.getBoolean( "insertable" ) ).isFalse();
assertThat( orderColumnUsage.getBoolean( "updatable" ) ).isFalse();
assertThat( orderColumnUsage.getBoolean( "nullable" ) ).isFalse();
}
@Test
public void testMapKeyNoAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm5.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
final AnnotationUsage<MapKey> mapKeyUsage = memberDetails.getAnnotationUsage( MapKey.class );
assertThat( mapKeyUsage.getString( "name" ) ).isEmpty();
}
@Test
public void testMapKeyAllAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm6.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
final AnnotationUsage<MapKey> mapKeyUsage = memberDetails.getAnnotationUsage( MapKey.class );
assertThat( mapKeyUsage.getString( "name" ) ).isEqualTo( "field2" );
}
@Test
public void testMapKeyClass() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm7.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
final AnnotationUsage<MapKeyClass> mapKeyClassUsage = memberDetails.getAnnotationUsage( MapKeyClass.class );
assertThat( mapKeyClassUsage.getClassDetails( "value" ).toJavaClass() ).isEqualTo( Entity2.class );
}
@Test
public void testMapKeyTemporal() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm8.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
final AnnotationUsage<MapKeyTemporal> mapKeyTemporalUsage = memberDetails.getAnnotationUsage( MapKeyTemporal.class );
assertThat( mapKeyTemporalUsage.getEnum( "value", TemporalType.class ) ).isEqualTo( TemporalType.DATE );
}
@Test
public void testMapKeyEnumerated() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm9.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
final AnnotationUsage<MapKeyEnumerated> mapKeyEnumeratedUsage = memberDetails.getAnnotationUsage( MapKeyEnumerated.class );
assertThat( mapKeyEnumeratedUsage.getEnum( "value", EnumType.class ) ).isEqualTo( EnumType.STRING );
}
/**
* When there's a single map key attribute override, we still wrap it with
* an AttributeOverrides annotation.
*/
@Test
public void testSingleMapKeyAttributeOverride() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm10.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverride.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverrides.class ) ).isFalse();
final AnnotationUsage<AttributeOverride> attributeOverrideUsage = memberDetails.getAnnotationUsage( AttributeOverride.class );
assertThat( attributeOverrideUsage.getString( "name" ) ).isEqualTo( "key.field1" );
final AnnotationUsage<Column> nestedColumnUsage = attributeOverrideUsage.getNestedUsage( "column" );
assertThat( nestedColumnUsage.getString( "name" ) ).isEqualTo( "col1" );
}
@Test
public void testMultipleMapKeyAttributeOverrides() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm11.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverrides.class ) ).isTrue();
final AnnotationUsage<AttributeOverrides> attributeOverridesUsage = memberDetails.getAnnotationUsage( AttributeOverrides.class );
final List<AnnotationUsage<AttributeOverride>> attributeOverrideUsages = attributeOverridesUsage.getList( "value" );
assertThat( attributeOverrideUsages ).hasSize( 2 );
final AnnotationUsage<AttributeOverride> attributeOverrideUsage0 = attributeOverrideUsages.get( 0 );
assertThat( attributeOverrideUsage0.getString( "name" ) ).isEqualTo( "key.field1" );
final AnnotationUsage<Column> nestedColumnUsage0 = attributeOverrideUsage0.getNestedUsage( "column" );
assertThat( nestedColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( nestedColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( nestedColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( nestedColumnUsage0.getBoolean( "nullable" ) ).isTrue();
assertThat( nestedColumnUsage0.getBoolean( "unique" ) ).isFalse();
assertThat( nestedColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( nestedColumnUsage0.getString( "table" ) ).isEmpty();
assertThat( nestedColumnUsage0.getInteger( "length" ) ).isEqualTo( 255 );
assertThat( nestedColumnUsage0.getInteger( "precision" ) ).isEqualTo( 0 );
assertThat( nestedColumnUsage0.getInteger( "scale" ) ).isEqualTo( 0 );
final AnnotationUsage<AttributeOverride> attributeOverrideUsage1 = attributeOverrideUsages.get( 1 );
assertThat( attributeOverrideUsage1.getString( "name" ) ).isEqualTo( "key.field2" );
final AnnotationUsage<Column> nestedColumnUsage1 = attributeOverrideUsage1.getNestedUsage( "column" );
assertThat( nestedColumnUsage1.getString( "name" ) ).isEqualTo( "col1" );
assertThat( nestedColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( nestedColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( nestedColumnUsage1.getBoolean( "nullable" ) ).isFalse();
assertThat( nestedColumnUsage1.getBoolean( "unique" ) ).isTrue();
assertThat( nestedColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( nestedColumnUsage1.getString( "table" ) ).isEqualTo( "table1" );
assertThat( nestedColumnUsage1.getInteger( "length" ) ).isEqualTo( 50 );
assertThat( nestedColumnUsage1.getInteger( "precision" ) ).isEqualTo( 2 );
assertThat( nestedColumnUsage1.getInteger( "scale" ) ).isEqualTo( 1 );
}
@Test
public void testMapKeyColumnNoAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm12.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isTrue();
final AnnotationUsage<MapKeyColumn> mapKeyColumnUsage = memberDetails.getAnnotationUsage( MapKeyColumn.class );
assertThat( mapKeyColumnUsage.getString( "name" ) ).isEmpty();
assertThat( mapKeyColumnUsage.getString( "table" ) ).isEmpty();
assertThat( mapKeyColumnUsage.getString( "columnDefinition" ) ).isEmpty();
assertThat( mapKeyColumnUsage.getBoolean( "nullable" ) ).isFalse();
assertThat( mapKeyColumnUsage.getBoolean( "insertable" ) ).isTrue();
assertThat( mapKeyColumnUsage.getBoolean( "updatable" ) ).isTrue();
assertThat( mapKeyColumnUsage.getBoolean( "unique" ) ).isFalse();
assertThat( mapKeyColumnUsage.getInteger( "length" ) ).isEqualTo( 255 );
assertThat( mapKeyColumnUsage.getInteger( "precision" ) ).isEqualTo( 0 );
assertThat( mapKeyColumnUsage.getInteger( "scale" ) ).isEqualTo( 0 );
}
@Test
public void testMapKeyColumnAllAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm13.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isTrue();
final AnnotationUsage<MapKeyColumn> mapKeyColumnUsage = memberDetails.getAnnotationUsage( MapKeyColumn.class );
assertThat( mapKeyColumnUsage.getString( "name" ) ).isEqualTo( "col1" );
assertThat( mapKeyColumnUsage.getString( "table" ) ).isEqualTo( "table1" );
assertThat( mapKeyColumnUsage.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( mapKeyColumnUsage.getBoolean( "nullable" ) ).isTrue();
assertThat( mapKeyColumnUsage.getBoolean( "insertable" ) ).isFalse();
assertThat( mapKeyColumnUsage.getBoolean( "updatable" ) ).isFalse();
assertThat( mapKeyColumnUsage.getBoolean( "unique" ) ).isTrue();
assertThat( mapKeyColumnUsage.getInteger( "length" ) ).isEqualTo( 50 );
assertThat( mapKeyColumnUsage.getInteger( "precision" ) ).isEqualTo( 2 );
assertThat( mapKeyColumnUsage.getInteger( "scale" ) ).isEqualTo( 1 );
}
/**
* When there's a single map key join column, we still wrap it with a
* MapKeyJoinColumns annotation.
*/
@Test
public void testSingleMapKeyJoinColumn() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm14.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
final AnnotationUsage<MapKeyJoinColumn> joinColumnUsage = memberDetails.getAnnotationUsage( MapKeyJoinColumn.class );
assertThat( joinColumnUsage.getString( "name" ) ).isEqualTo( "col1" );
}
@Test
public void testMultipleMapKeyJoinColumns() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm15.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyJoinColumns.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( MapKey.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyClass.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyTemporal.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyEnumerated.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( MapKeyColumn.class ) ).isFalse();
final AnnotationUsage<MapKeyJoinColumns> joinColumnsUsage = memberDetails.getAnnotationUsage( MapKeyJoinColumns.class );
final List<AnnotationUsage<MapKeyJoinColumn>> joinColumnUsages = joinColumnsUsage.getList( "value" );
assertThat( joinColumnUsages ).hasSize( 2 );
final AnnotationUsage<MapKeyJoinColumn> joinColumnUsage0 = joinColumnUsages.get( 0 );
assertThat( joinColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "referencedColumnName" ) ).isEmpty();
assertThat( joinColumnUsage0.getBoolean( "unique" ) ).isFalse();
assertThat( joinColumnUsage0.getBoolean( "nullable" ) ).isFalse();
assertThat( joinColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( joinColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "table" ) ).isEmpty();
final AnnotationUsage<MapKeyJoinColumn> joinColumnUsage1 = joinColumnUsages.get( 1 );
assertThat( joinColumnUsage1.getString( "name" ) ).isEqualTo( "col1" );
assertThat( joinColumnUsage1.getString( "referencedColumnName" ) ).isEqualTo( "col2" );
assertThat( joinColumnUsage1.getBoolean( "unique" ) ).isTrue();
assertThat( joinColumnUsage1.getBoolean( "nullable" ) ).isTrue();
assertThat( joinColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( joinColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( joinColumnUsage1.getString( "table" ) ).isEqualTo( "table1" );
}
@Test
public void testColumnNoAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm16.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( Column.class ) ).isTrue();
final AnnotationUsage<Column> columnUsage = memberDetails.getAnnotationUsage( Column.class );
assertThat( columnUsage.getString( "name" ) ).isEmpty();
assertThat( columnUsage.getBoolean( "unique" ) ).isFalse();
assertThat( columnUsage.getBoolean( "nullable" ) ).isTrue();
assertThat( columnUsage.getBoolean( "insertable" ) ).isTrue();
assertThat( columnUsage.getBoolean( "updatable" ) ).isTrue();
assertThat( columnUsage.getString( "columnDefinition" ) ).isEmpty();
assertThat( columnUsage.getString( "table" ) ).isEmpty();
assertThat( columnUsage.getInteger( "length" ) ).isEqualTo( 255 );
assertThat( columnUsage.getInteger( "precision" ) ).isEqualTo( 0 );
assertThat( columnUsage.getInteger( "scale" ) ).isEqualTo( 0 );
}
@Test
public void testColumnAllAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm17.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( Column.class ) ).isTrue();
final AnnotationUsage<Column> columnUsage = memberDetails.getAnnotationUsage( Column.class );
assertThat( columnUsage.getString( "name" ) ).isEqualTo( "col1" );
assertThat( columnUsage.getBoolean( "unique" ) ).isTrue();
assertThat( columnUsage.getBoolean( "nullable" ) ).isFalse();
assertThat( columnUsage.getBoolean( "insertable" ) ).isFalse();
assertThat( columnUsage.getBoolean( "updatable" ) ).isFalse();
assertThat( columnUsage.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( columnUsage.getString( "table" ) ).isEqualTo( "table1" );
assertThat( columnUsage.getInteger( "length" ) ).isEqualTo( 50 );
assertThat( columnUsage.getInteger( "precision" ) ).isEqualTo( 2 );
assertThat( columnUsage.getInteger( "scale" ) ).isEqualTo( 1 );
}
@Test
public void testTemporal() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm18.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( Temporal.class ) ).isTrue();
final AnnotationUsage<Temporal> temporalUsage = memberDetails.getAnnotationUsage( Temporal.class );
assertThat( temporalUsage.getEnum( "value", TemporalType.class ) ).isEqualTo( TemporalType.DATE );
}
@Test
public void testEnumerated() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm19.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( Enumerated.class ) ).isTrue();
final AnnotationUsage<Enumerated> enumeratedUsage = memberDetails.getAnnotationUsage( Enumerated.class );
assertThat( enumeratedUsage.getEnum( "value", EnumType.class ) ).isEqualTo( EnumType.STRING );
}
@Test
public void testLob() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm20.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( Lob.class ) ).isTrue();
}
/**
* When there's a single attribute override, we still wrap it with an
* AttributeOverrides annotation.
*/
@Test
public void testSingleAttributeOverride() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm21.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverride.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverrides.class ) ).isFalse();
final AnnotationUsage<AttributeOverride> overrideUsage = memberDetails.getAnnotationUsage( AttributeOverride.class );
assertThat( overrideUsage.getString( "name" ) ).isEqualTo( "value.field1" );
final AnnotationUsage<Annotation> overrideColumnUsage = overrideUsage.getNestedUsage( "column" );
assertThat( overrideColumnUsage.getString( "name" ) ).isEqualTo( "col1" );
}
@Test
public void testMultipleAttributeOverrides() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm22.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverride.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverrides.class ) ).isTrue();
final AnnotationUsage<AttributeOverrides> overridesUsage = memberDetails.getAnnotationUsage( AttributeOverrides.class );
final List<AnnotationUsage<AttributeOverride>> overrideUsages = overridesUsage.getList( "value" );
assertThat( overrideUsages ).hasSize( 2 );
final AnnotationUsage<AttributeOverride> overrideUsage0 = overrideUsages.get( 0 );
assertThat( overrideUsage0.getString( "name" ) ).isEqualTo( "value.field1" );
final AnnotationUsage<Column> overrideColumnUsage0 = overrideUsage0.getNestedUsage( "column" );
assertThat( overrideColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( overrideColumnUsage0.getBoolean( "unique" ) ).isFalse();
assertThat( overrideColumnUsage0.getBoolean( "nullable" ) ).isTrue();
assertThat( overrideColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( overrideColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( overrideColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( overrideColumnUsage0.getString( "table" ) ).isEmpty();
assertThat( overrideColumnUsage0.getInteger( "length" ) ).isEqualTo( 255 );
assertThat( overrideColumnUsage0.getInteger( "precision" ) ).isEqualTo( 0 );
assertThat( overrideColumnUsage0.getInteger( "scale" ) ).isEqualTo( 0 );
final AnnotationUsage<AttributeOverride> overrideUsage1 = overrideUsages.get( 1 );
assertThat( overrideUsage1.getString( "name" ) ).isEqualTo( "value.field2" );
final AnnotationUsage<Column> overrideColumnUsage1 = overrideUsage1.getNestedUsage( "column" );
assertThat( overrideColumnUsage1.getString( "name" ) ).isEqualTo( "col1" );
assertThat( overrideColumnUsage1.getBoolean( "unique" ) ).isTrue();
assertThat( overrideColumnUsage1.getBoolean( "nullable" ) ).isFalse();
assertThat( overrideColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( overrideColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( overrideColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( overrideColumnUsage1.getString( "table" ) ).isEqualTo( "table1" );
assertThat( overrideColumnUsage1.getInteger( "length" ) ).isEqualTo( 50 );
assertThat( overrideColumnUsage1.getInteger( "precision" ) ).isEqualTo( 2 );
assertThat( overrideColumnUsage1.getInteger( "scale" ) ).isEqualTo( 1 );
}
/**
* Tests that map-key-attribute-override and attribute-override elements
* both end up in the AttributeOverrides annotation.
*/
@Test
public void testMixedAttributeOverrides() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm23.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverride.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AttributeOverrides.class ) ).isTrue();
final AnnotationUsage<AttributeOverrides> overridesUsage = memberDetails.getAnnotationUsage( AttributeOverrides.class );
final List<AnnotationUsage<AttributeOverride>> overrideUsages = overridesUsage.getList( "value" );
assertThat( overrideUsages ).hasSize( 2 );
final AnnotationUsage<AttributeOverride> overrideUsage0 = overrideUsages.get( 0 );
assertThat( overrideUsage0.getString( "name" ) ).isEqualTo( "key.field1" );
final AnnotationUsage<Column> overrideColumnUsage0 = overrideUsage0.getNestedUsage( "column" );
assertThat( overrideColumnUsage0.getString( "name" ) ).isEqualTo( "col1" );
final AnnotationUsage<AttributeOverride> overrideUsage1 = overrideUsages.get( 1 );
assertThat( overrideUsage1.getString( "name" ) ).isEqualTo( "value.field2" );
final AnnotationUsage<Column> overrideColumnUsage1 = overrideUsage1.getNestedUsage( "column" );
assertThat( overrideColumnUsage1.getString( "name" ) ).isEqualTo( "col2" );
}
/**
* When there's a single association override, we still wrap it with an
* AssociationOverrides annotation.
*/
@Test
public void testSingleAssociationOverride() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm24.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AssociationOverride.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AssociationOverrides.class ) ).isFalse();
final AnnotationUsage<AssociationOverride> overrideUsage = memberDetails.getAnnotationUsage( AssociationOverride.class );
assertThat( overrideUsage.getString( "name" ) ).isEqualTo( "association1" );
assertThat( overrideUsage.getList( "joinColumns" ) ).isEmpty();
final AnnotationUsage<Annotation> joinTableUsage = overrideUsage.getNestedUsage( "joinTable" );
assertThat( joinTableUsage.getString( "name" ) ).isEmpty();
}
@Test
public void testMultipleAssociationOverridesJoinColumns() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm25.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( AssociationOverride.class ) ).isFalse();
assertThat( memberDetails.hasAnnotationUsage( AssociationOverrides.class ) ).isTrue();
final AnnotationUsage<AssociationOverrides> overridesUsage = memberDetails.getAnnotationUsage( AssociationOverrides.class );
final List<AnnotationUsage<AssociationOverrides>> overrideUsages = overridesUsage.getList( "value" );
assertThat( overrideUsages ).hasSize( 2 );
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// First, an association using join table
final AnnotationUsage<AssociationOverrides> overrideUsage = overrideUsages.get( 0 );
assertThat( overrideUsage.getString( "name" ) ).isEqualTo( "association1" );
assertThat( overrideUsage.getList( "joinColumns" ) ).isEmpty();
AnnotationUsage<Annotation> joinTableUsage = overrideUsage.getNestedUsage( "joinTable" );
assertThat( joinTableUsage.getString( "catalog" ) ).isEqualTo( "catalog1" );
assertThat( joinTableUsage.getString( "name" ) ).isEqualTo( "table1" );
assertThat( joinTableUsage.getString( "schema" ) ).isEqualTo( "schema1" );
//JoinColumns
final List<AnnotationUsage<JoinColumn>> joinColumUsages = joinTableUsage.getList( "joinColumns" );
assertThat( joinColumUsages ).hasSize( 2 );
final AnnotationUsage<JoinColumn> joinColumnUsage0 = joinColumUsages.get( 0 );
assertThat( joinColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "referencedColumnName" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "table" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( joinColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "nullable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "unique" ) ).isFalse();
final AnnotationUsage<JoinColumn> joinColumnUsage1 = joinColumUsages.get( 1 );
assertThat( joinColumnUsage1.getString( "name" ) ).isEqualTo( "col1" );
assertThat( joinColumnUsage1.getString( "referencedColumnName" ) ).isEqualTo( "col2" );
assertThat( joinColumnUsage1.getString( "table" ) ).isEqualTo( "table2" );
assertThat( joinColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( joinColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "nullable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "unique" ) ).isTrue();
//InverseJoinColumns
final List<AnnotationUsage<JoinColumn>> inverseJoinColumnUsages = joinTableUsage.getList( "inverseJoinColumns" );
assertThat( inverseJoinColumnUsages ).hasSize( 2 );
final AnnotationUsage<JoinColumn> inverseJoinColumnUsage0 = inverseJoinColumnUsages.get( 0 );
assertThat( inverseJoinColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( inverseJoinColumnUsage0.getString( "referencedColumnName" ) ).isEmpty();
assertThat( inverseJoinColumnUsage0.getString( "table" ) ).isEmpty();
assertThat( inverseJoinColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( inverseJoinColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( inverseJoinColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( inverseJoinColumnUsage0.getBoolean( "nullable" ) ).isTrue();
assertThat( inverseJoinColumnUsage0.getBoolean( "unique" ) ).isFalse();
final AnnotationUsage<JoinColumn> inverseJoinColumnUsage1 = inverseJoinColumnUsages.get( 1 );
assertThat( inverseJoinColumnUsage1.getString( "name" ) ).isEqualTo( "col3" );
assertThat( inverseJoinColumnUsage1.getString( "referencedColumnName" ) ).isEqualTo( "col4" );
assertThat( inverseJoinColumnUsage1.getString( "table" ) ).isEqualTo( "table3" );
assertThat( inverseJoinColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( inverseJoinColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( inverseJoinColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( inverseJoinColumnUsage1.getBoolean( "nullable" ) ).isFalse();
assertThat( inverseJoinColumnUsage1.getBoolean( "unique" ) ).isTrue();
//UniqueConstraints
final List<AnnotationUsage<UniqueConstraint>> uniqueConstraintUsages = joinTableUsage.getList( "uniqueConstraints" );
assertThat( uniqueConstraintUsages ).hasSize( 2 );
final AnnotationUsage<UniqueConstraint> uniqueConstraintUsage0 = uniqueConstraintUsages.get( 0 );
assertThat( uniqueConstraintUsage0.getString( "name" ) ).isEmpty();
assertThat( uniqueConstraintUsage0.getList( "columnNames" ) ).containsOnly( "col5" );
final AnnotationUsage<UniqueConstraint> uniqueConstraintUsage1 = uniqueConstraintUsages.get( 1 );
assertThat( uniqueConstraintUsage1.getString( "name" ) ).isEqualTo( "uq1" );
assertThat( uniqueConstraintUsage1.getList( "columnNames" ) ).containsOnly( "col6", "col7" );
}
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Second, an association using join columns
final AnnotationUsage<AssociationOverrides> overrideUsage = overrideUsages.get( 1 );
assertThat( overrideUsage.getString( "name" ) ).isEqualTo( "association2" );
//JoinColumns
final List<AnnotationUsage<JoinColumn>> joinColumUsages = overrideUsage.getList( "joinColumns" );
assertThat( joinColumUsages ).hasSize( 2 );
final AnnotationUsage<JoinColumn> joinColumnUsage0 = joinColumUsages.get( 0 );
assertThat( joinColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "referencedColumnName" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "table" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( joinColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "nullable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "unique" ) ).isFalse();
final AnnotationUsage<JoinColumn> joinColumnUsage1 = joinColumUsages.get( 1 );
assertThat( joinColumnUsage1.getString( "name" ) ).isEqualTo( "col8" );
assertThat( joinColumnUsage1.getString( "referencedColumnName" ) ).isEqualTo( "col9" );
assertThat( joinColumnUsage1.getString( "table" ) ).isEqualTo( "table4" );
assertThat( joinColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( joinColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "nullable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "unique" ) ).isTrue();
}
}
@Test
public void testCollectionTableNoChildren() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm26.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( CollectionTable.class ) ).isTrue();
final AnnotationUsage<CollectionTable> collectionTableUsage = memberDetails.getAnnotationUsage( CollectionTable.class );
assertThat( collectionTableUsage.getString( "name" ) ).isEmpty();
assertThat( collectionTableUsage.getString( "catalog" ) ).isEmpty();
assertThat( collectionTableUsage.getString( "schema" ) ).isEmpty();
assertThat( collectionTableUsage.getList( "joinColumns" ) ).isEmpty();
assertThat( collectionTableUsage.getList( "uniqueConstraints" ) ).isEmpty();
}
@Test
public void testCollectionTableAllChildren() {
final MemberDetails memberDetails = getAttributeMember( Entity3.class, "field1", "element-collection.orm27.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
assertThat( memberDetails.hasAnnotationUsage( CollectionTable.class ) ).isTrue();
final AnnotationUsage<CollectionTable> collectionTableUsage = memberDetails.getAnnotationUsage( CollectionTable.class );
assertThat( collectionTableUsage.getString( "name" ) ).isEqualTo( "table1" );
assertThat( collectionTableUsage.getString( "catalog" ) ).isEqualTo( "catalog1" );
assertThat( collectionTableUsage.getString( "schema" ) ).isEqualTo( "schema1" );
//JoinColumns
final List<AnnotationUsage<JoinColumn>> joinColumnUsages = collectionTableUsage.getList( "joinColumns" );
assertThat( joinColumnUsages ).hasSize( 2 );
final AnnotationUsage<JoinColumn> joinColumnUsage0 = joinColumnUsages.get( 0 );
assertThat( joinColumnUsage0.getString( "name" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "referencedColumnName" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "table" ) ).isEmpty();
assertThat( joinColumnUsage0.getString( "columnDefinition" ) ).isEmpty();
assertThat( joinColumnUsage0.getBoolean( "insertable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "updatable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "nullable" ) ).isTrue();
assertThat( joinColumnUsage0.getBoolean( "unique" ) ).isFalse();
final AnnotationUsage<JoinColumn> joinColumnUsage1 = joinColumnUsages.get( 1 );
assertThat( joinColumnUsage1.getString( "name" ) ).isEqualTo( "col1" );
assertThat( joinColumnUsage1.getString( "referencedColumnName" ) ).isEqualTo( "col2" );
assertThat( joinColumnUsage1.getString( "table" ) ).isEqualTo( "table2" );
assertThat( joinColumnUsage1.getString( "columnDefinition" ) ).isEqualTo( "int" );
assertThat( joinColumnUsage1.getBoolean( "insertable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "updatable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "nullable" ) ).isFalse();
assertThat( joinColumnUsage1.getBoolean( "unique" ) ).isTrue();
//UniqueConstraints
final List<AnnotationUsage<UniqueConstraint>> uniqueConstraintUsages = collectionTableUsage.getList( "uniqueConstraints" );
assertThat( uniqueConstraintUsages ).hasSize( 2 );
final AnnotationUsage<UniqueConstraint> uniqueConstraintUsage0 = uniqueConstraintUsages.get( 0 );
assertThat( uniqueConstraintUsage0.getString( "name" ) ).isEmpty();
assertThat( uniqueConstraintUsage0.getList( "columnNames" ) ).containsOnly( "col3" );
final AnnotationUsage<UniqueConstraint> uniqueConstraintUsage1 = uniqueConstraintUsages.get( 1 );
assertThat( uniqueConstraintUsage1.getString( "name" ) ).isEqualTo( "uq1" );
assertThat( uniqueConstraintUsage1.getList( "columnNames" ) ).containsOnly( "col4", "col5" );
}
@Test
public void testAllAttributes() {
final MemberDetails memberDetails = getAttributeMember( Entity2.class, "field1", "element-collection.orm28.xml" );
assertThat( memberDetails.hasAnnotationUsage( ElementCollection.class ) ).isTrue();
final AnnotationUsage<ElementCollection> elementCollectionUsage = memberDetails.getAnnotationUsage( ElementCollection.class );
assertThat( elementCollectionUsage.getEnum( "fetch", FetchType.class ) ).isEqualTo( FetchType.EAGER );
final AnnotationUsage<Access> accessUsage = memberDetails.getAnnotationUsage( Access.class );
assertThat( accessUsage.getEnum( "value", AccessType.class ) ).isEqualTo( AccessType.PROPERTY );
final AnnotationUsage<Target> targetUsage = memberDetails.getAnnotationUsage( Target.class );
assertThat( targetUsage.getString( "value" ) ).isEqualTo( Entity3.class.getName() );
}
}

View File

@ -120,12 +120,19 @@ public class DynamicModelTests {
final FieldDetails labels = rootEntity.getClassDetails().findFieldByName( "labels" ); final FieldDetails labels = rootEntity.getClassDetails().findFieldByName( "labels" );
assertThat( labels.getType().determineRawClass().getClassName() ).isEqualTo( Set.class.getName() ); assertThat( labels.getType().determineRawClass().getClassName() ).isEqualTo( Set.class.getName() );
final AnnotationUsage<ElementCollection> elementCollection = labels.getAnnotationUsage( ElementCollection.class ); final AnnotationUsage<ElementCollection> elementCollection = labels.getAnnotationUsage( ElementCollection.class );
assertThat( elementCollection.<ClassDetails>getAttributeValue( "targetClass" ).getName() ).isEqualTo( String.class.getName() );
assertThat( elementCollection.getClassDetails( "targetClass" ) ).isEqualTo( ClassDetails.VOID_CLASS_DETAILS );
final AnnotationUsage<Target> targetUsage = labels.getAnnotationUsage( Target.class );
assertThat( targetUsage.getString( "value" ) ).isEqualTo( "string" );
final AnnotationUsage<CollectionClassification> collectionClassification = labels.getAnnotationUsage( CollectionClassification.class ); final AnnotationUsage<CollectionClassification> collectionClassification = labels.getAnnotationUsage( CollectionClassification.class );
assertThat( collectionClassification.<LimitedCollectionClassification>getAttributeValue( "value" ) ).isEqualTo( LimitedCollectionClassification.SET ); assertThat( collectionClassification.<LimitedCollectionClassification>getAttributeValue( "value" ) ).isEqualTo( LimitedCollectionClassification.SET );
assertThat( labels.getAnnotationUsage( SortNatural.class ) ).isNotNull();
final AnnotationUsage<CollectionTable> collectionTable = labels.getAnnotationUsage( CollectionTable.class ); final AnnotationUsage<CollectionTable> collectionTable = labels.getAnnotationUsage( CollectionTable.class );
assertThat( collectionTable.<String>getAttributeValue( "name" ) ).isEqualTo( "labels" ); assertThat( collectionTable.<String>getAttributeValue( "name" ) ).isEqualTo( "labels" );
assertThat( labels.getAnnotationUsage( SortNatural.class ) ).isNotNull();
final List<AnnotationUsage<JoinColumn>> joinColumns = collectionTable.getList( "joinColumns" ); final List<AnnotationUsage<JoinColumn>> joinColumns = collectionTable.getList( "joinColumns" );
assertThat( joinColumns ).hasSize( 1 ); assertThat( joinColumns ).hasSize( 1 );
assertThat( joinColumns.get( 0 ).<String>getAttributeValue( "name" ) ).isEqualTo( "contact_fk" ); assertThat( joinColumns.get( 0 ).<String>getAttributeValue( "name" ) ).isEqualTo( "contact_fk" );