From 9d71b1c85576a6d81c0bcb4541d8816385e071bf Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Thu, 14 Mar 2024 14:01:04 +0100 Subject: [PATCH] HHH-17504 - Ongoing JPA 32 work HHH-17350 - Work on hibernate-models, XSD and JAXB HHH-16114 - Improve boot metamodel binding HHH-15996 - Develop an abstraction for Annotation in annotation processing HHH-16012 - Develop an abstraction for domain model Class refs HHH-15997 - Support for dynamic models in orm.xml HHH-15698 - Support for entity-name in mapping.xsd --- .../xml/internal/XmlAnnotationHelper.java | 85 +++++++++++++++++++ .../xml/internal/XmlProcessingHelper.java | 24 ++++++ .../ElementCollectionAttributeProcessing.java | 25 ++---- .../xml/internal/db/ColumnProcessing.java | 75 +++++++++------- 4 files changed, 162 insertions(+), 47 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java index f3e869c220..1554625f46 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlAnnotationHelper.java @@ -219,6 +219,16 @@ public class XmlAnnotationHelper { return createJoinColumnAnnotation( jaxbJoinColumn, memberDetails, JoinColumn.class, xmlDocumentContext ); } + public static MutableAnnotationUsage applyJoinColumn( + JaxbJoinColumnImpl jaxbJoinColumn, + XmlDocumentContext xmlDocumentContext) { + if ( jaxbJoinColumn == null ) { + return null; + } + + return createJoinColumnAnnotation( jaxbJoinColumn, JoinColumn.class, xmlDocumentContext ); + } + public static MutableAnnotationUsage createJoinColumnAnnotation( JaxbColumnJoined jaxbJoinColumn, MutableMemberDetails memberDetails, @@ -245,6 +255,31 @@ public class XmlAnnotationHelper { return joinColumnAnn; } + public static MutableAnnotationUsage createJoinColumnAnnotation( + JaxbColumnJoined jaxbJoinColumn, + Class annotationType, + XmlDocumentContext xmlDocumentContext) { + final MutableAnnotationUsage joinColumnAnn = XmlProcessingHelper.getOrMakeAnnotation( annotationType, xmlDocumentContext ); + final AnnotationDescriptor joinColumnDescriptor = xmlDocumentContext + .getModelBuildingContext() + .getAnnotationDescriptorRegistry() + .getDescriptor( annotationType ); + + ColumnProcessing.applyColumnDetails( jaxbJoinColumn, joinColumnAnn, xmlDocumentContext ); + + applyOr( jaxbJoinColumn, JaxbColumnJoined::getReferencedColumnName, "referencedColumnName", joinColumnAnn, joinColumnDescriptor ); + + final JaxbForeignKeyImpl jaxbForeignKey = jaxbJoinColumn.getForeignKey(); + if ( jaxbForeignKey != null ) { + joinColumnAnn.setAttributeValue( + "foreignKey", + createForeignKeyAnnotation( jaxbForeignKey, xmlDocumentContext ) + ); + } + + return joinColumnAnn; + } + public static void applyJoinColumns( List jaxbJoinColumns, MutableMemberDetails memberDetails, @@ -280,6 +315,19 @@ public class XmlAnnotationHelper { return joinColumns; } + public static List> createJoinColumns( + List jaxbJoinColumns, + XmlDocumentContext xmlDocumentContext) { + if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) { + return Collections.emptyList(); + } + final List> joinColumns = new ArrayList<>( jaxbJoinColumns.size() ); + jaxbJoinColumns.forEach( jaxbJoinColumn -> { + joinColumns.add( applyJoinColumn( jaxbJoinColumn, xmlDocumentContext ) ); + } ); + return joinColumns; + } + public static void applyOr( N jaxbNode, Function jaxbValueAccess, @@ -429,6 +477,23 @@ public class XmlAnnotationHelper { return foreignKeyAnn; } + public static MutableAnnotationUsage createForeignKeyAnnotation( + JaxbForeignKeyImpl jaxbForeignKey, + XmlDocumentContext xmlDocumentContext) { + final MutableAnnotationUsage foreignKeyAnn = XmlProcessingHelper.getOrMakeAnnotation( ForeignKey.class, xmlDocumentContext ); + final AnnotationDescriptor foreignKeyDescriptor = xmlDocumentContext + .getModelBuildingContext() + .getAnnotationDescriptorRegistry() + .getDescriptor( ForeignKey.class ); + + applyOr( jaxbForeignKey, JaxbForeignKeyImpl::getName, "name", foreignKeyAnn, foreignKeyDescriptor ); + applyOr( jaxbForeignKey, JaxbForeignKeyImpl::getConstraintMode, "value", foreignKeyAnn, foreignKeyDescriptor ); + applyOr( jaxbForeignKey, JaxbForeignKeyImpl::getForeignKeyDefinition, "foreignKeyDefinition", foreignKeyAnn, foreignKeyDescriptor ); + applyOr( jaxbForeignKey, JaxbForeignKeyImpl::getOptions, "options", foreignKeyAnn, foreignKeyDescriptor ); + + return foreignKeyAnn; + } + public static void applyMapKeyColumn( JaxbMapKeyColumnImpl jaxbMapKeyColumn, MutableMemberDetails memberDetails, @@ -622,6 +687,26 @@ public class XmlAnnotationHelper { } } + public static void applyCheckConstraints( + JaxbCheckable jaxbCheckable, + MutableAnnotationUsage annotationUsage, + XmlDocumentContext xmlDocumentContext) { + if ( CollectionHelper.isNotEmpty( jaxbCheckable.getCheckConstraints() ) ) { + final List> checks = new ArrayList<>( jaxbCheckable.getCheckConstraints().size() ); + final AnnotationDescriptor checkConstraintDescriptor = xmlDocumentContext.getModelBuildingContext() + .getAnnotationDescriptorRegistry() + .getDescriptor( CheckConstraint.class ); + for ( JaxbCheckConstraintImpl jaxbCheck : jaxbCheckable.getCheckConstraints() ) { + final MutableAnnotationUsage checkAnn = XmlProcessingHelper.getOrMakeAnnotation( CheckConstraint.class, xmlDocumentContext ); + applyOr( jaxbCheck, JaxbCheckConstraintImpl::getName, "name", checkAnn, checkConstraintDescriptor ); + applyOr( jaxbCheck, JaxbCheckConstraintImpl::getConstraint, "constraint", checkAnn, checkConstraintDescriptor ); + applyOr( jaxbCheck, JaxbCheckConstraintImpl::getOptions, "options", checkAnn, checkConstraintDescriptor ); + checks.add( checkAnn ); + } + annotationUsage.setAttributeValue( "check", checks ); + } + } + public static void applyTargetClass( String name, MutableMemberDetails memberDetails, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlProcessingHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlProcessingHelper.java index 9f042377ae..9132470054 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlProcessingHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/XmlProcessingHelper.java @@ -125,6 +125,13 @@ public class XmlProcessingHelper { return makeAnnotation( annotationType, target, xmlDocumentContext ); } + public static MutableAnnotationUsage getOrMakeAnnotation( + Class annotationType, + XmlDocumentContext xmlDocumentContext) { + + return makeAnnotation( annotationType, xmlDocumentContext ); + } + /** * Make a nested AnnotationUsage. The usage is created with the given target, * but it is not added to the target's annotations. @@ -141,6 +148,16 @@ public class XmlProcessingHelper { ); } + public static MutableAnnotationUsage makeNestedAnnotation( + Class annotationType, + XmlDocumentContext xmlDocumentContext) { + return new DynamicAnnotationUsage<>( + xmlDocumentContext.getModelBuildingContext() + .getAnnotationDescriptorRegistry() + .getDescriptor( annotationType ) + ); + } + /** * Make an AnnotationUsage. * Used when applying XML in complete mode or when {@linkplain #getOrMakeAnnotation} @@ -155,6 +172,13 @@ public class XmlProcessingHelper { return created; } + public static MutableAnnotationUsage makeAnnotation( + Class annotationType, + XmlDocumentContext xmlDocumentContext) { + final MutableAnnotationUsage created = makeNestedAnnotation( annotationType, xmlDocumentContext ); + return created; + } + /** * Find an existing annotation by name, or create one. * Used when applying XML in override mode. diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/ElementCollectionAttributeProcessing.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/ElementCollectionAttributeProcessing.java index e6ce746b2d..5120c46bb7 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/ElementCollectionAttributeProcessing.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/attr/ElementCollectionAttributeProcessing.java @@ -48,15 +48,13 @@ public class ElementCollectionAttributeProcessing { xmlDocumentContext ); XmlProcessingHelper.setIf( jaxbElementCollection.getFetch(), "fetch", elementCollectionAnn ); - if ( StringHelper.isNotEmpty( jaxbElementCollection.getTargetClass() ) ) { - elementCollectionAnn.setAttributeValue( - "targetClass", - XmlAnnotationHelper.resolveJavaType( - jaxbElementCollection.getTargetClass(), - xmlDocumentContext.getModelBuildingContext() - ) - ); - } + elementCollectionAnn.setAttributeValue( + "targetClass", + XmlAnnotationHelper.resolveJavaType( + jaxbElementCollection.getTargetClass(), + xmlDocumentContext.getModelBuildingContext() + ) + ); CommonAttributeProcessing.applyAttributeBasics( jaxbElementCollection, memberDetails, elementCollectionAnn, accessType, xmlDocumentContext ); @@ -73,11 +71,6 @@ public class ElementCollectionAttributeProcessing { XmlAnnotationHelper.applyTemporal( jaxbElementCollection.getTemporal(), memberDetails, xmlDocumentContext ); XmlAnnotationHelper.applyBasicTypeComposition( jaxbElementCollection, memberDetails, xmlDocumentContext ); - if ( StringHelper.isNotEmpty( jaxbElementCollection.getTargetClass() ) ) { - final MutableAnnotationUsage targetAnn = XmlProcessingHelper.getOrMakeAnnotation( Target.class, memberDetails, xmlDocumentContext ); - targetAnn.setAttributeValue( "value", jaxbElementCollection.getTargetClass() ); - } - jaxbElementCollection.getConverts().forEach( (jaxbConvert) -> { XmlAnnotationHelper.applyConvert( jaxbConvert, memberDetails, xmlDocumentContext ); } ); @@ -110,12 +103,12 @@ public class ElementCollectionAttributeProcessing { XmlAnnotationHelper.applyOr( jaxbCollectionTable, JaxbCollectionTableImpl::getSchema, "schema", collectionTableAnn, collectionTableDescriptor ); XmlAnnotationHelper.applyOr( jaxbCollectionTable, JaxbCollectionTableImpl::getOptions, "options", collectionTableAnn, collectionTableDescriptor ); - collectionTableAnn.setAttributeValue( "joinColumns", XmlAnnotationHelper.createJoinColumns( jaxbCollectionTable.getJoinColumns(), memberDetails, xmlDocumentContext ) ); + collectionTableAnn.setAttributeValue( "joinColumns", XmlAnnotationHelper.createJoinColumns( jaxbCollectionTable.getJoinColumns(), xmlDocumentContext ) ); if ( jaxbCollectionTable.getForeignKeys() != null ) { collectionTableAnn.setAttributeValue( "foreignKey", - XmlAnnotationHelper.createForeignKeyAnnotation( jaxbCollectionTable.getForeignKeys(), memberDetails, xmlDocumentContext ) + XmlAnnotationHelper.createForeignKeyAnnotation( jaxbCollectionTable.getForeignKeys(), xmlDocumentContext ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/db/ColumnProcessing.java b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/db/ColumnProcessing.java index 2122dcd22f..3e622f8126 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/db/ColumnProcessing.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/xml/internal/db/ColumnProcessing.java @@ -38,37 +38,57 @@ public class ColumnProcessing { return; } - applyColumnBasics( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnNullness( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnMutability( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnDefinition( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnUniqueness( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnComment( jaxbColumn, target, columnAnn, xmlDocumentContext ); + applyColumnBasics( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnNullness( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnMutability( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnDefinition( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnUniqueness( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnComment( jaxbColumn, columnAnn, xmlDocumentContext ); XmlAnnotationHelper.applyCheckConstraints( jaxbColumn, target, columnAnn, xmlDocumentContext ); if ( jaxbColumn instanceof JaxbColumnSizable sizable ) { - applyColumnSizing( sizable, target, columnAnn, xmlDocumentContext ); + applyColumnSizing( sizable, columnAnn, xmlDocumentContext ); } } public static void applyColumnDetails( - JaxbColumnStandard jaxbColumn, - MutableAnnotationTarget target, + JaxbColumnCommon jaxbColumn, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( jaxbColumn == null ) { return; } - applyColumnBasics( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnNullness( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnMutability( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnDefinition( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnSizing( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnUniqueness( jaxbColumn, target, columnAnn, xmlDocumentContext ); - applyColumnComment( jaxbColumn, target, columnAnn, xmlDocumentContext ); - XmlAnnotationHelper.applyCheckConstraints( jaxbColumn, target, columnAnn, xmlDocumentContext ); + applyColumnBasics( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnNullness( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnMutability( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnDefinition( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnUniqueness( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnComment( jaxbColumn, columnAnn, xmlDocumentContext ); + XmlAnnotationHelper.applyCheckConstraints( jaxbColumn, columnAnn, xmlDocumentContext ); + + if ( jaxbColumn instanceof JaxbColumnSizable sizable ) { + applyColumnSizing( sizable, columnAnn, xmlDocumentContext ); + } + } + + public static void applyColumnDetails( + JaxbColumnStandard jaxbColumn, + MutableAnnotationUsage columnAnn, + XmlDocumentContext xmlDocumentContext) { + if ( jaxbColumn == null ) { + return; + } + + applyColumnBasics( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnNullness( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnMutability( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnDefinition( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnSizing( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnUniqueness( jaxbColumn, columnAnn, xmlDocumentContext ); + applyColumnComment( jaxbColumn, columnAnn, xmlDocumentContext ); + XmlAnnotationHelper.applyCheckConstraints( jaxbColumn, columnAnn, xmlDocumentContext ); } public static void applyColumnDetails( @@ -80,30 +100,30 @@ public class ColumnProcessing { return; } - applyColumnBasics( jaxbColumn, target, columnAnn, xmlDocumentContext ); + applyColumnBasics( jaxbColumn, columnAnn, xmlDocumentContext ); if ( jaxbColumn instanceof JaxbColumnNullable nullable ) { - applyColumnNullness( nullable, target, columnAnn, xmlDocumentContext ); + applyColumnNullness( nullable, columnAnn, xmlDocumentContext ); } if ( jaxbColumn instanceof JaxbColumnMutable mutable ) { - applyColumnMutability( mutable, target, columnAnn, xmlDocumentContext ); + applyColumnMutability( mutable, columnAnn, xmlDocumentContext ); } if ( jaxbColumn instanceof JaxbColumnDefinable definable ) { - applyColumnDefinition( definable, target, columnAnn, xmlDocumentContext ); + applyColumnDefinition( definable, columnAnn, xmlDocumentContext ); } if ( jaxbColumn instanceof JaxbColumnSizable sizable ) { - applyColumnSizing( sizable, target, columnAnn, xmlDocumentContext ); + applyColumnSizing( sizable, columnAnn, xmlDocumentContext ); } if ( jaxbColumn instanceof JaxbColumnUniqueable uniqueable ) { - applyColumnUniqueness( uniqueable, target, columnAnn, xmlDocumentContext ); + applyColumnUniqueness( uniqueable, columnAnn, xmlDocumentContext ); } if ( jaxbColumn instanceof JaxbCommentable commentable ) { - applyColumnComment( commentable, target, columnAnn, xmlDocumentContext ); + applyColumnComment( commentable, columnAnn, xmlDocumentContext ); } if ( jaxbColumn instanceof JaxbCheckable checkable ) { @@ -113,7 +133,6 @@ public class ColumnProcessing { private static void applyColumnBasics( JaxbColumn jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( StringHelper.isNotEmpty( jaxbColumn.getName() ) ) { @@ -127,7 +146,6 @@ public class ColumnProcessing { private static void applyColumnNullness( JaxbColumnNullable jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( jaxbColumn.isNullable() != null ) { @@ -137,7 +155,6 @@ public class ColumnProcessing { private static void applyColumnMutability( JaxbColumnMutable jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( jaxbColumn.isInsertable() != null ) { @@ -151,7 +168,6 @@ public class ColumnProcessing { private static void applyColumnSizing( JaxbColumnSizable jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { @@ -170,7 +186,6 @@ public class ColumnProcessing { private static void applyColumnUniqueness( JaxbColumnUniqueable jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( jaxbColumn.isUnique() != null ) { @@ -180,7 +195,6 @@ public class ColumnProcessing { private static void applyColumnDefinition( JaxbColumnDefinable jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( StringHelper.isNotEmpty( jaxbColumn.getColumnDefinition() ) ) { @@ -194,7 +208,6 @@ public class ColumnProcessing { private static void applyColumnComment( JaxbCommentable jaxbColumn, - MutableAnnotationTarget target, MutableAnnotationUsage columnAnn, XmlDocumentContext xmlDocumentContext) { if ( StringHelper.isNotEmpty( jaxbColumn.getComment() ) ) {