Search in sources :

Example 1 with CollectionTable

use of jakarta.persistence.CollectionTable in project hibernate-orm by hibernate.

the class AnnotationBinder method bindJoinedTableAssociation.

// TODO move that to collection binder?
private static void bindJoinedTableAssociation(XProperty property, MetadataBuildingContext buildingContext, EntityBinder entityBinder, CollectionBinder collectionBinder, PropertyHolder propertyHolder, PropertyData inferredData, String mappedBy) {
    TableBinder associationTableBinder = new TableBinder();
    JoinColumn[] annJoins;
    JoinColumn[] annInverseJoins;
    JoinTable assocTable = propertyHolder.getJoinTable(property);
    CollectionTable collectionTable = property.getAnnotation(CollectionTable.class);
    if (assocTable != null || collectionTable != null) {
        final String catalog;
        final String schema;
        final String tableName;
        final UniqueConstraint[] uniqueConstraints;
        final JoinColumn[] joins;
        final JoinColumn[] inverseJoins;
        final jakarta.persistence.Index[] jpaIndexes;
        // JPA 2 has priority
        if (collectionTable != null) {
            catalog = collectionTable.catalog();
            schema = collectionTable.schema();
            tableName = collectionTable.name();
            uniqueConstraints = collectionTable.uniqueConstraints();
            joins = collectionTable.joinColumns();
            inverseJoins = null;
            jpaIndexes = collectionTable.indexes();
        } else {
            catalog = assocTable.catalog();
            schema = assocTable.schema();
            tableName = assocTable.name();
            uniqueConstraints = assocTable.uniqueConstraints();
            joins = assocTable.joinColumns();
            inverseJoins = assocTable.inverseJoinColumns();
            jpaIndexes = assocTable.indexes();
        }
        collectionBinder.setExplicitAssociationTable(true);
        if (jpaIndexes != null && jpaIndexes.length > 0) {
            associationTableBinder.setJpaIndex(jpaIndexes);
        }
        if (!BinderHelper.isEmptyAnnotationValue(schema)) {
            associationTableBinder.setSchema(schema);
        }
        if (!BinderHelper.isEmptyAnnotationValue(catalog)) {
            associationTableBinder.setCatalog(catalog);
        }
        if (!BinderHelper.isEmptyAnnotationValue(tableName)) {
            associationTableBinder.setName(tableName);
        }
        associationTableBinder.setUniqueConstraints(uniqueConstraints);
        associationTableBinder.setJpaIndex(jpaIndexes);
        // set check constraint in the second pass
        annJoins = joins.length == 0 ? null : joins;
        annInverseJoins = inverseJoins == null || inverseJoins.length == 0 ? null : inverseJoins;
    } else {
        annJoins = null;
        annInverseJoins = null;
    }
    AnnotatedJoinColumn[] joinColumns = buildJoinTableJoinColumns(annJoins, entityBinder.getSecondaryTables(), propertyHolder, inferredData.getPropertyName(), mappedBy, buildingContext);
    AnnotatedJoinColumn[] inverseJoinColumns = buildJoinTableJoinColumns(annInverseJoins, entityBinder.getSecondaryTables(), propertyHolder, inferredData.getPropertyName(), mappedBy, buildingContext);
    associationTableBinder.setBuildingContext(buildingContext);
    collectionBinder.setTableBinder(associationTableBinder);
    collectionBinder.setJoinColumns(joinColumns);
    collectionBinder.setInverseJoinColumns(inverseJoinColumns);
}
Also used : UniqueConstraint(jakarta.persistence.UniqueConstraint) Index(org.hibernate.annotations.Index) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) CollectionTable(jakarta.persistence.CollectionTable) TableBinder(org.hibernate.cfg.annotations.TableBinder) JoinTable(jakarta.persistence.JoinTable)

Example 2 with CollectionTable

use of jakarta.persistence.CollectionTable in project hibernate-orm by hibernate.

the class CollectionBinder method buildCollectionKey.

private static DependantValue buildCollectionKey(Collection collValue, AnnotatedJoinColumn[] joinColumns, boolean cascadeDeleteEnabled, boolean noConstraintByDefault, XProperty property, PropertyHolder propertyHolder, MetadataBuildingContext buildingContext) {
    // has to do that here because the referencedProperty creation happens in a FKSecondPass for Many to one yuk!
    if (joinColumns.length > 0 && StringHelper.isNotEmpty(joinColumns[0].getMappedBy())) {
        String entityName = joinColumns[0].getManyToManyOwnerSideEntityName() != null ? "inverse__" + joinColumns[0].getManyToManyOwnerSideEntityName() : joinColumns[0].getPropertyHolder().getEntityName();
        InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector();
        String propRef = metadataCollector.getPropertyReferencedAssociation(entityName, joinColumns[0].getMappedBy());
        if (propRef != null) {
            collValue.setReferencedPropertyName(propRef);
            metadataCollector.addPropertyReference(collValue.getOwnerEntityName(), propRef);
        }
    }
    String propRef = collValue.getReferencedPropertyName();
    // binding key reference using column
    KeyValue keyVal = propRef == null ? collValue.getOwner().getIdentifier() : (KeyValue) collValue.getOwner().getReferencedProperty(propRef).getValue();
    DependantValue key = new DependantValue(buildingContext, collValue.getCollectionTable(), keyVal);
    key.setTypeName(null);
    checkPropertyConsistency(joinColumns, collValue.getOwnerEntityName());
    key.setNullable(joinColumns.length == 0 || joinColumns[0].isNullable());
    key.setUpdateable(joinColumns.length == 0 || joinColumns[0].isUpdatable());
    key.setCascadeDeleteEnabled(cascadeDeleteEnabled);
    collValue.setKey(key);
    if (property != null) {
        final ForeignKey fk = property.getAnnotation(ForeignKey.class);
        if (fk != null && !isEmptyAnnotationValue(fk.name())) {
            key.setForeignKeyName(fk.name());
        } else {
            final CollectionTable collectionTableAnn = property.getAnnotation(CollectionTable.class);
            if (collectionTableAnn != null) {
                if (collectionTableAnn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT || collectionTableAnn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault) {
                    key.disableForeignKey();
                } else {
                    key.setForeignKeyName(StringHelper.nullIfEmpty(collectionTableAnn.foreignKey().name()));
                    key.setForeignKeyDefinition(StringHelper.nullIfEmpty(collectionTableAnn.foreignKey().foreignKeyDefinition()));
                    if (key.getForeignKeyName() == null && key.getForeignKeyDefinition() == null && collectionTableAnn.joinColumns().length == 1) {
                        JoinColumn joinColumn = collectionTableAnn.joinColumns()[0];
                        key.setForeignKeyName(StringHelper.nullIfEmpty(joinColumn.foreignKey().name()));
                        key.setForeignKeyDefinition(StringHelper.nullIfEmpty(joinColumn.foreignKey().foreignKeyDefinition()));
                    }
                }
            } else {
                final JoinTable joinTableAnn = property.getAnnotation(JoinTable.class);
                if (joinTableAnn != null) {
                    String foreignKeyName = joinTableAnn.foreignKey().name();
                    String foreignKeyDefinition = joinTableAnn.foreignKey().foreignKeyDefinition();
                    ConstraintMode foreignKeyValue = joinTableAnn.foreignKey().value();
                    if (joinTableAnn.joinColumns().length != 0) {
                        final JoinColumn joinColumnAnn = joinTableAnn.joinColumns()[0];
                        if (foreignKeyName != null && foreignKeyName.isEmpty()) {
                            foreignKeyName = joinColumnAnn.foreignKey().name();
                            foreignKeyDefinition = joinColumnAnn.foreignKey().foreignKeyDefinition();
                        }
                        if (foreignKeyValue != ConstraintMode.NO_CONSTRAINT) {
                            foreignKeyValue = joinColumnAnn.foreignKey().value();
                        }
                    }
                    if (foreignKeyValue == ConstraintMode.NO_CONSTRAINT || foreignKeyValue == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault) {
                        key.disableForeignKey();
                    } else {
                        key.setForeignKeyName(StringHelper.nullIfEmpty(foreignKeyName));
                        key.setForeignKeyDefinition(StringHelper.nullIfEmpty(foreignKeyDefinition));
                    }
                } else {
                    final jakarta.persistence.ForeignKey fkOverride = propertyHolder.getOverriddenForeignKey(StringHelper.qualify(propertyHolder.getPath(), property.getName()));
                    if (fkOverride != null && (fkOverride.value() == ConstraintMode.NO_CONSTRAINT || fkOverride.value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault)) {
                        key.disableForeignKey();
                    } else if (fkOverride != null) {
                        key.setForeignKeyName(StringHelper.nullIfEmpty(fkOverride.name()));
                        key.setForeignKeyDefinition(StringHelper.nullIfEmpty(fkOverride.foreignKeyDefinition()));
                    } else {
                        final OneToMany oneToManyAnn = property.getAnnotation(OneToMany.class);
                        final OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
                        if (oneToManyAnn != null && !oneToManyAnn.mappedBy().isEmpty() && (onDeleteAnn == null || onDeleteAnn.action() != OnDeleteAction.CASCADE)) {
                            // foreign key should be up to @ManyToOne side
                            // @OnDelete generate "on delete cascade" foreign key
                            key.disableForeignKey();
                        } else {
                            final JoinColumn joinColumnAnn = property.getAnnotation(JoinColumn.class);
                            if (joinColumnAnn != null) {
                                if (joinColumnAnn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT || joinColumnAnn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault) {
                                    key.disableForeignKey();
                                } else {
                                    key.setForeignKeyName(StringHelper.nullIfEmpty(joinColumnAnn.foreignKey().name()));
                                    key.setForeignKeyDefinition(StringHelper.nullIfEmpty(joinColumnAnn.foreignKey().foreignKeyDefinition()));
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return key;
}
Also used : KeyValue(org.hibernate.mapping.KeyValue) DependantValue(org.hibernate.mapping.DependantValue) ConstraintMode(jakarta.persistence.ConstraintMode) ForeignKey(org.hibernate.annotations.ForeignKey) OneToMany(jakarta.persistence.OneToMany) InFlightMetadataCollector(org.hibernate.boot.spi.InFlightMetadataCollector) JoinColumn(jakarta.persistence.JoinColumn) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) CollectionTable(jakarta.persistence.CollectionTable) JoinTable(jakarta.persistence.JoinTable) WhereJoinTable(org.hibernate.annotations.WhereJoinTable) FilterJoinTable(org.hibernate.annotations.FilterJoinTable) OnDelete(org.hibernate.annotations.OnDelete)

Example 3 with CollectionTable

use of jakarta.persistence.CollectionTable in project hibernate-orm by hibernate.

the class Ejb3XmlElementCollectionTest method testCollectionTableNoChildren.

@Test
public void testCollectionTableNoChildren() throws Exception {
    reader = getReader(Entity3.class, "field1", "element-collection.orm26.xml");
    assertAnnotationPresent(ElementCollection.class);
    assertAnnotationPresent(CollectionTable.class);
    CollectionTable tableAnno = reader.getAnnotation(CollectionTable.class);
    assertEquals("", tableAnno.name());
    assertEquals("", tableAnno.catalog());
    assertEquals("", tableAnno.schema());
    assertEquals(0, tableAnno.joinColumns().length);
    assertEquals(0, tableAnno.uniqueConstraints().length);
}
Also used : CollectionTable(jakarta.persistence.CollectionTable) Test(org.junit.Test)

Example 4 with CollectionTable

use of jakarta.persistence.CollectionTable in project hibernate-orm by hibernate.

the class Ejb3XmlElementCollectionTest method testCollectionTableAllChildren.

@Test
public void testCollectionTableAllChildren() throws Exception {
    reader = getReader(Entity3.class, "field1", "element-collection.orm27.xml");
    assertAnnotationPresent(ElementCollection.class);
    assertAnnotationPresent(CollectionTable.class);
    CollectionTable tableAnno = reader.getAnnotation(CollectionTable.class);
    assertEquals("table1", tableAnno.name());
    assertEquals("catalog1", tableAnno.catalog());
    assertEquals("schema1", tableAnno.schema());
    // JoinColumns
    JoinColumn[] joinColumns = tableAnno.joinColumns();
    assertEquals(2, joinColumns.length);
    assertEquals("", joinColumns[0].name());
    assertEquals("", joinColumns[0].referencedColumnName());
    assertEquals("", joinColumns[0].table());
    assertEquals("", joinColumns[0].columnDefinition());
    assertTrue(joinColumns[0].insertable());
    assertTrue(joinColumns[0].updatable());
    assertTrue(joinColumns[0].nullable());
    assertFalse(joinColumns[0].unique());
    assertEquals("col1", joinColumns[1].name());
    assertEquals("col2", joinColumns[1].referencedColumnName());
    assertEquals("table2", joinColumns[1].table());
    assertEquals("int", joinColumns[1].columnDefinition());
    assertFalse(joinColumns[1].insertable());
    assertFalse(joinColumns[1].updatable());
    assertFalse(joinColumns[1].nullable());
    assertTrue(joinColumns[1].unique());
    // UniqueConstraints
    UniqueConstraint[] uniqueConstraints = tableAnno.uniqueConstraints();
    assertEquals(2, uniqueConstraints.length);
    assertEquals("", uniqueConstraints[0].name());
    assertEquals(1, uniqueConstraints[0].columnNames().length);
    assertEquals("col3", uniqueConstraints[0].columnNames()[0]);
    assertEquals("uq1", uniqueConstraints[1].name());
    assertEquals(2, uniqueConstraints[1].columnNames().length);
    assertEquals("col4", uniqueConstraints[1].columnNames()[0]);
    assertEquals("col5", uniqueConstraints[1].columnNames()[1]);
}
Also used : MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) CollectionTable(jakarta.persistence.CollectionTable) UniqueConstraint(jakarta.persistence.UniqueConstraint) Test(org.junit.Test)

Aggregations

CollectionTable (jakarta.persistence.CollectionTable)4 JoinColumn (jakarta.persistence.JoinColumn)3 JoinTable (jakarta.persistence.JoinTable)2 MapKeyJoinColumn (jakarta.persistence.MapKeyJoinColumn)2 UniqueConstraint (jakarta.persistence.UniqueConstraint)2 Test (org.junit.Test)2 ConstraintMode (jakarta.persistence.ConstraintMode)1 OneToMany (jakarta.persistence.OneToMany)1 PrimaryKeyJoinColumn (jakarta.persistence.PrimaryKeyJoinColumn)1 FilterJoinTable (org.hibernate.annotations.FilterJoinTable)1 ForeignKey (org.hibernate.annotations.ForeignKey)1 Index (org.hibernate.annotations.Index)1 OnDelete (org.hibernate.annotations.OnDelete)1 WhereJoinTable (org.hibernate.annotations.WhereJoinTable)1 InFlightMetadataCollector (org.hibernate.boot.spi.InFlightMetadataCollector)1 AnnotatedJoinColumn (org.hibernate.cfg.AnnotatedJoinColumn)1 TableBinder (org.hibernate.cfg.annotations.TableBinder)1 DependantValue (org.hibernate.mapping.DependantValue)1 KeyValue (org.hibernate.mapping.KeyValue)1