HHH-18081 XML <secondary-table/> element is not added to JdkClassDetails

This commit is contained in:
Andrea Boriero 2024-05-07 17:54:14 +02:00 committed by Steve Ebersole
parent a594a8c9b7
commit 905e86a04d
6 changed files with 148 additions and 5 deletions

View File

@ -517,6 +517,7 @@ public class ManagedTypeProcessor {
}
XmlAnnotationHelper.applyTable( jaxbEntity.getTable(), classDetails, xmlDocumentContext );
XmlAnnotationHelper.applySecondaryTables( jaxbEntity.getSecondaryTables(), classDetails, xmlDocumentContext );
final JaxbAttributesContainerImpl attributes = jaxbEntity.getAttributes();
if ( attributes != null ) {

View File

@ -53,7 +53,6 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorFormulaImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerContainerImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityOrMappedSuperclass;
import org.hibernate.boot.jaxb.mapping.spi.JaxbGeneratedValueImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbHbmFilterImpl;
@ -63,12 +62,12 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLifecycleCallback;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLifecycleCallbackContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLobImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNotFoundCapable;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSchemaAware;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSecondaryTableImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGeneratorImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTableImpl;
@ -88,7 +87,6 @@ import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
import org.hibernate.boot.models.xml.internal.db.TableProcessing;
import org.hibernate.boot.models.xml.spi.XmlDocument;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.util.KeyedConsumer;
import org.hibernate.internal.util.StringHelper;
@ -125,6 +123,8 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.IdClass;
import jakarta.persistence.Index;
import jakarta.persistence.Inheritance;
import jakarta.persistence.SecondaryTable;
import jakarta.persistence.SecondaryTables;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.TableGenerator;
@ -1500,4 +1500,43 @@ public class XmlAnnotationHelper {
);
notFoundAnn.setAttributeValue( "action", notFoundAction );
}
public static void applySecondaryTables(List<JaxbSecondaryTableImpl> secondaryTables, MutableAnnotationTarget target, XmlDocumentContext xmlDocumentContext) {
if ( secondaryTables == null || secondaryTables.isEmpty() ) {
return;
}
final MutableAnnotationUsage<SecondaryTables> listenersUsage = target.replaceAnnotationUsage(
JpaAnnotations.SECONDARY_TABLE,
JpaAnnotations.SECONDARY_TABLES,
xmlDocumentContext.getModelBuildingContext()
);
final List<MutableAnnotationUsage<SecondaryTable>> values = arrayList( secondaryTables.size() );
listenersUsage.setAttributeValue( "value", values );
for ( JaxbSecondaryTableImpl secondaryTable : secondaryTables ) {
final MutableAnnotationUsage<SecondaryTable> tableAnn = JpaAnnotations.SECONDARY_TABLE
.createUsage( xmlDocumentContext.getModelBuildingContext() );
tableAnn.setAttributeValue( "name", secondaryTable.getName() );
ForeignKeyProcessing.applyForeignKey( secondaryTable.getForeignKey(), tableAnn, xmlDocumentContext );
JoinColumnProcessing.applyPrimaryKeyJoinColumns(
secondaryTable.getPrimaryKeyJoinColumn(),
tableAnn,
xmlDocumentContext
);
applyTableAttributes(
secondaryTable,
target,
tableAnn,
JpaAnnotations.SECONDARY_TABLE,
xmlDocumentContext
);
values.add( tableAnn );
}
}
}

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.boot.models.xml.internal.db;
import java.lang.annotation.Annotation;
import org.hibernate.boot.jaxb.mapping.spi.JaxbForeignKeyImpl;
import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
@ -79,4 +81,38 @@ public class ForeignKeyProcessing {
return foreignKeyUsage;
}
public static <A extends Annotation> void applyForeignKey(
JaxbForeignKeyImpl jaxbForeignKey,
MutableAnnotationUsage<A> tableAnn,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbForeignKey == null ) {
return;
}
final MutableAnnotationUsage<ForeignKey> foreignKeyUsage = JpaAnnotations.FOREIGN_KEY.createUsage(
xmlDocumentContext.getModelBuildingContext()
);
XmlAnnotationHelper.applyOptionalAttribute( foreignKeyUsage, "name", jaxbForeignKey.getName() );
XmlAnnotationHelper.applyOptionalAttribute(
foreignKeyUsage,
"value",
jaxbForeignKey.getConstraintMode()
);
XmlAnnotationHelper.applyOptionalAttribute(
foreignKeyUsage,
"foreignKeyDefinition",
jaxbForeignKey.getForeignKeyDefinition()
);
XmlAnnotationHelper.applyOptionalAttribute(
foreignKeyUsage,
"options",
jaxbForeignKey.getOptions()
);
tableAnn.setAttributeValue(
"foreignkey",
foreignKeyUsage
);;
}
}

View File

@ -183,4 +183,44 @@ public class JoinColumnProcessing {
);
columnsAnn.setAttributeValue( "value", createJoinColumns( jaxbJoinColumns, memberDetails, xmlDocumentContext ) );
}
public static <A extends Annotation> void applyPrimaryKeyJoinColumns(
List<JaxbPrimaryKeyJoinColumnImpl> jaxbJoinColumns,
MutableAnnotationUsage<A> tableAnn,
XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return;
}
final List<MutableAnnotationUsage<PrimaryKeyJoinColumn>> columnUsages = CollectionHelper.arrayList( jaxbJoinColumns.size() );
jaxbJoinColumns.forEach( (jaxbJoinColumn) -> {
final MutableAnnotationUsage<PrimaryKeyJoinColumn> columnUsage =
JpaAnnotations.PRIMARY_KEY_JOIN_COLUMN.createUsage( xmlDocumentContext.getModelBuildingContext() );
columnUsages.add( columnUsage );
ColumnProcessing.applyColumnDetails(
jaxbJoinColumn,
(MutableAnnotationUsage<? extends Annotation>) columnUsage,
xmlDocumentContext
);
XmlAnnotationHelper.applyOptionalAttribute(
columnUsage,
"referencedColumnName",
((JaxbColumnJoined) jaxbJoinColumn).getReferencedColumnName()
);
ForeignKeyProcessing.applyForeignKey(
( (JaxbColumnJoined) jaxbJoinColumn ).getForeignKey(),
(MutableAnnotationUsage<? extends Annotation>) columnUsage,
xmlDocumentContext
);
} );
tableAnn.setAttributeValue(
"pkJoinColumns",
columnUsages
);
}
}

View File

@ -420,6 +420,16 @@
</bindings>
</bindings>
<bindings node=".//xsd:complexType[@name='secondary-table']">
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.db.JaxbTableMapping</inheritance:implements>
<bindings node=".//xsd:element[@name='unique-constraint']">
<property name="uniqueConstraints"/>
</bindings>
<bindings node=".//xsd:element[@name='index']">
<property name="indexes"/>
</bindings>
</bindings>
<bindings node="//xsd:complexType[@name='check-constraint']">
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.db.JaxbCheckConstraint</inheritance:implements>
</bindings>

View File

@ -10,6 +10,8 @@ import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
@ -46,16 +48,31 @@ public class SecondaryTableTest {
@Test
public void testSecondaryTablesAreCreated() throws Exception {
createSchema( "org/hibernate/orm/test/schemaupdate/secondarytable/TestEntity.xml" );
assertTrue(
isTableCreated( output, "CATALOG1.SCHEMA1.SECONDARY_TABLE_1" ),
isTableCreated( output, getExpectedTableName( "SECONDARY_TABLE_1", "SCHEMA1", "CATALOG1" ) ),
"Table SECONDARY_TABLE_1 has not been created "
);
assertTrue(
isTableCreated( output, "SECONDARY_TABLE_2" ),
isTableCreated( output, getExpectedTableName( "SECONDARY_TABLE_2", null, null ) ),
"Table SECONDARY_TABLE_2 has not been created "
);
}
private String getExpectedTableName(String tableName, String schema, String catalog) {
String expectedTableName = tableName;
NameQualifierSupport nameQualifierSupport = metadata.getDatabase()
.getJdbcEnvironment()
.getNameQualifierSupport();
if ( StringHelper.isNotEmpty( schema ) && nameQualifierSupport.supportsSchemas() ) {
expectedTableName = schema + "." + expectedTableName;
}
if ( StringHelper.isNotEmpty( catalog ) && nameQualifierSupport.supportsCatalogs() ) {
expectedTableName = catalog + "." + expectedTableName;
}
return expectedTableName;
}
private static boolean isTableCreated(
File output,
String tableName) throws Exception {