Search in sources :

Example 1 with AnnotatedJoinColumn

use of org.hibernate.cfg.AnnotatedJoinColumn in project hibernate-orm by hibernate.

the class EntityBinder method createPrimaryColumnsToSecondaryTable.

private void createPrimaryColumnsToSecondaryTable(Object uncastedColumn, PropertyHolder propertyHolder, Join join) {
    AnnotatedJoinColumn[] annotatedJoinColumns;
    PrimaryKeyJoinColumn[] pkColumnsAnn = null;
    JoinColumn[] joinColumnsAnn = null;
    if (uncastedColumn instanceof PrimaryKeyJoinColumn[]) {
        pkColumnsAnn = (PrimaryKeyJoinColumn[]) uncastedColumn;
    }
    if (uncastedColumn instanceof JoinColumn[]) {
        joinColumnsAnn = (JoinColumn[]) uncastedColumn;
    }
    if (pkColumnsAnn == null && joinColumnsAnn == null) {
        annotatedJoinColumns = new AnnotatedJoinColumn[1];
        annotatedJoinColumns[0] = AnnotatedJoinColumn.buildJoinColumn(null, null, persistentClass.getIdentifier(), secondaryTables, propertyHolder, context);
    } else {
        int nbrOfJoinColumns = pkColumnsAnn != null ? pkColumnsAnn.length : joinColumnsAnn.length;
        if (nbrOfJoinColumns == 0) {
            annotatedJoinColumns = new AnnotatedJoinColumn[1];
            annotatedJoinColumns[0] = AnnotatedJoinColumn.buildJoinColumn(null, null, persistentClass.getIdentifier(), secondaryTables, propertyHolder, context);
        } else {
            annotatedJoinColumns = new AnnotatedJoinColumn[nbrOfJoinColumns];
            if (pkColumnsAnn != null) {
                for (int colIndex = 0; colIndex < nbrOfJoinColumns; colIndex++) {
                    annotatedJoinColumns[colIndex] = AnnotatedJoinColumn.buildJoinColumn(pkColumnsAnn[colIndex], null, persistentClass.getIdentifier(), secondaryTables, propertyHolder, context);
                }
            } else {
                for (int colIndex = 0; colIndex < nbrOfJoinColumns; colIndex++) {
                    annotatedJoinColumns[colIndex] = AnnotatedJoinColumn.buildJoinColumn(null, joinColumnsAnn[colIndex], persistentClass.getIdentifier(), secondaryTables, propertyHolder, context);
                }
            }
        }
    }
    for (AnnotatedJoinColumn joinColumn : annotatedJoinColumns) {
        joinColumn.forceNotNull();
    }
    bindJoinToPersistentClass(join, annotatedJoinColumns, context);
}
Also used : PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn)

Example 2 with AnnotatedJoinColumn

use of org.hibernate.cfg.AnnotatedJoinColumn in project hibernate-orm by hibernate.

the class CollectionBinder method handleOwnedManyToMany.

private void handleOwnedManyToMany(Collection collValue, AnnotatedJoinColumn[] joinColumns, TableBinder associationTableBinder, XProperty property, MetadataBuildingContext buildingContext, PersistentClass collectionEntity, boolean isCollectionOfEntities) {
    // FIXME NamingStrategy
    for (AnnotatedJoinColumn column : joinColumns) {
        String mappedByProperty = buildingContext.getMetadataCollector().getFromMappedBy(collValue.getOwnerEntityName(), column.getPropertyName());
        Table ownerTable = collValue.getOwner().getTable();
        column.setMappedBy(collValue.getOwner().getEntityName(), collValue.getOwner().getJpaEntityName(), buildingContext.getMetadataCollector().getLogicalTableName(ownerTable), mappedByProperty);
    // String header = ( mappedByProperty == null ) ? mappings.getLogicalTableName( ownerTable ) : mappedByProperty;
    // column.setDefaultColumnHeader( header );
    }
    if (StringHelper.isEmpty(associationTableBinder.getName())) {
        // default value
        associationTableBinder.setDefaultName(collValue.getOwner().getClassName(), collValue.getOwner().getEntityName(), collValue.getOwner().getJpaEntityName(), buildingContext.getMetadataCollector().getLogicalTableName(collValue.getOwner().getTable()), collectionEntity != null ? collectionEntity.getClassName() : null, collectionEntity != null ? collectionEntity.getEntityName() : null, collectionEntity != null ? collectionEntity.getJpaEntityName() : null, collectionEntity != null ? buildingContext.getMetadataCollector().getLogicalTableName(collectionEntity.getTable()) : null, joinColumns[0].getPropertyName());
    }
    associationTableBinder.setJPA2ElementCollection(!isCollectionOfEntities && property.isAnnotationPresent(ElementCollection.class));
    collValue.setCollectionTable(associationTableBinder.bind());
}
Also used : CollectionTable(jakarta.persistence.CollectionTable) JoinTable(jakarta.persistence.JoinTable) WhereJoinTable(org.hibernate.annotations.WhereJoinTable) Table(org.hibernate.mapping.Table) FilterJoinTable(org.hibernate.annotations.FilterJoinTable) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn)

Example 3 with AnnotatedJoinColumn

use of org.hibernate.cfg.AnnotatedJoinColumn in project hibernate-orm by hibernate.

the class CollectionBinder method handleUnownedManyToMany.

private void handleUnownedManyToMany(Collection collValue, AnnotatedJoinColumn[] joinColumns, XClass collType, PersistentClass collectionEntity, boolean isCollectionOfEntities) {
    if (!isCollectionOfEntities) {
        throw new AnnotationException("Collection of elements must not have mappedBy or association reference an unmapped entity: " + collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName());
    }
    Property otherSideProperty;
    try {
        otherSideProperty = collectionEntity.getRecursiveProperty(joinColumns[0].getMappedBy());
    } catch (MappingException e) {
        throw new AnnotationException("mappedBy references an unknown target entity property: " + collType + "." + joinColumns[0].getMappedBy() + " in " + collValue.getOwnerEntityName() + "." + joinColumns[0].getPropertyName());
    }
    Table table;
    if (otherSideProperty.getValue() instanceof Collection) {
        // this is a collection on the other side
        table = ((Collection) otherSideProperty.getValue()).getCollectionTable();
    } else {
        // This is a ToOne with a @JoinTable or a regular property
        table = otherSideProperty.getValue().getTable();
    }
    collValue.setCollectionTable(table);
    String entityName = collectionEntity.getEntityName();
    for (AnnotatedJoinColumn column : joinColumns) {
        // column.setDefaultColumnHeader( joinColumns[0].getMappedBy() ); //seems not to be used, make sense
        column.setManyToManyOwnerSideEntityName(entityName);
    }
}
Also used : CollectionTable(jakarta.persistence.CollectionTable) JoinTable(jakarta.persistence.JoinTable) WhereJoinTable(org.hibernate.annotations.WhereJoinTable) Table(org.hibernate.mapping.Table) FilterJoinTable(org.hibernate.annotations.FilterJoinTable) AnnotationException(org.hibernate.AnnotationException) LazyCollection(org.hibernate.annotations.LazyCollection) ElementCollection(jakarta.persistence.ElementCollection) Collection(org.hibernate.mapping.Collection) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) Property(org.hibernate.mapping.Property) XProperty(org.hibernate.annotations.common.reflection.XProperty) MappingException(org.hibernate.MappingException)

Example 4 with AnnotatedJoinColumn

use of org.hibernate.cfg.AnnotatedJoinColumn in project hibernate-orm by hibernate.

the class CollectionBinderTest method testAssociatedClassException.

@Test
@TestForIssue(jiraKey = "HHH-10106")
public void testAssociatedClassException() throws SQLException {
    final Collection collection = mock(Collection.class);
    final XClass collectionType = mock(XClass.class);
    final MetadataBuildingContext buildingContext = mock(MetadataBuildingContext.class);
    final InFlightMetadataCollector inFly = mock(InFlightMetadataCollector.class);
    final PersistentClass persistentClass = mock(PersistentClass.class);
    final Table table = mock(Table.class);
    when(buildingContext.getMetadataCollector()).thenReturn(inFly);
    when(collection.getOwner()).thenReturn(persistentClass);
    when(collectionType.getName()).thenReturn("List");
    when(persistentClass.getTable()).thenReturn(table);
    when(table.getName()).thenReturn("Hibernate");
    String expectMessage = "Association [abc] for entity [CollectionBinderTest] references unmapped class [List]";
    try {
        new CollectionBinder(null, false, buildingContext) {

            {
                final PropertyHolder propertyHolder = Mockito.mock(PropertyHolder.class);
                when(propertyHolder.getClassName()).thenReturn(CollectionBinderTest.class.getSimpleName());
                this.propertyName = "abc";
                setPropertyHolder(propertyHolder);
            }

            @Override
            protected Collection createCollection(PersistentClass persistentClass) {
                return null;
            }

            @Override
            public void bindOneToManySecondPass(Collection collection, Map<String, PersistentClass> persistentClasses, AnnotatedJoinColumn[] fkJoinColumns, XClass collectionType, boolean cascadeDeleteEnabled, boolean ignoreNotFound, MetadataBuildingContext buildingContext, Map<XClass, InheritanceState> inheritanceStatePerClass) {
                super.bindOneToManySecondPass(collection, persistentClasses, fkJoinColumns, collectionType, cascadeDeleteEnabled, ignoreNotFound, buildingContext, inheritanceStatePerClass);
            }
        }.bindOneToManySecondPass(collection, new HashMap(), null, collectionType, false, false, buildingContext, null);
    } catch (MappingException e) {
        assertEquals(expectMessage, e.getMessage());
    }
}
Also used : Table(org.hibernate.mapping.Table) HashMap(java.util.HashMap) MetadataBuildingContext(org.hibernate.boot.spi.MetadataBuildingContext) XClass(org.hibernate.annotations.common.reflection.XClass) MappingException(org.hibernate.MappingException) InheritanceState(org.hibernate.cfg.InheritanceState) InFlightMetadataCollector(org.hibernate.boot.spi.InFlightMetadataCollector) PropertyHolder(org.hibernate.cfg.PropertyHolder) Collection(org.hibernate.mapping.Collection) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) CollectionBinder(org.hibernate.cfg.annotations.CollectionBinder) PersistentClass(org.hibernate.mapping.PersistentClass) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Example 5 with AnnotatedJoinColumn

use of org.hibernate.cfg.AnnotatedJoinColumn 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)

Aggregations

AnnotatedJoinColumn (org.hibernate.cfg.AnnotatedJoinColumn)10 Collection (org.hibernate.mapping.Collection)4 PersistentClass (org.hibernate.mapping.PersistentClass)4 Property (org.hibernate.mapping.Property)4 CollectionTable (jakarta.persistence.CollectionTable)3 JoinColumn (jakarta.persistence.JoinColumn)3 JoinTable (jakarta.persistence.JoinTable)3 AnnotationException (org.hibernate.AnnotationException)3 AssertionFailure (org.hibernate.AssertionFailure)3 MappingException (org.hibernate.MappingException)3 FilterJoinTable (org.hibernate.annotations.FilterJoinTable)3 WhereJoinTable (org.hibernate.annotations.WhereJoinTable)3 XProperty (org.hibernate.annotations.common.reflection.XProperty)3 Column (org.hibernate.mapping.Column)3 Table (org.hibernate.mapping.Table)3 ElementCollection (jakarta.persistence.ElementCollection)2 OneToMany (jakarta.persistence.OneToMany)2 HashMap (java.util.HashMap)2 LazyCollection (org.hibernate.annotations.LazyCollection)2 XClass (org.hibernate.annotations.common.reflection.XClass)2