Search in sources :

Example 1 with JoinTable

use of jakarta.persistence.JoinTable 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 JoinTable

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

the class AnnotationBinder method bindAny.

private static void bindAny(PropertyHolder propertyHolder, Nullability nullability, PropertyData inferredData, EntityBinder entityBinder, boolean isIdentifierMapper, MetadataBuildingContext context, XProperty property, AnnotatedJoinColumn[] joinColumns, boolean forcePersist) {
    // check validity
    if (property.isAnnotationPresent(Columns.class)) {
        throw new AnnotationException(String.format(Locale.ROOT, "@Columns not allowed on a @Any property [%s]; @Column or @Formula is used to map the discriminator" + "and only one is allowed", BinderHelper.getPath(propertyHolder, inferredData)));
    }
    Cascade hibernateCascade = property.getAnnotation(Cascade.class);
    OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
    JoinTable assocTable = propertyHolder.getJoinTable(property);
    if (assocTable != null) {
        Join join = propertyHolder.addJoin(assocTable, false);
        for (AnnotatedJoinColumn joinColumn : joinColumns) {
            joinColumn.setExplicitTableName(join.getTable().getName());
        }
    }
    bindAny(getCascadeStrategy(null, hibernateCascade, false, forcePersist), // @Any has not cascade attribute
    joinColumns, onDeleteAnn != null && OnDeleteAction.CASCADE == onDeleteAnn.action(), nullability, propertyHolder, inferredData, entityBinder, isIdentifierMapper, context);
}
Also used : AnnotationException(org.hibernate.AnnotationException) Join(org.hibernate.mapping.Join) Cascade(org.hibernate.annotations.Cascade) OnDelete(org.hibernate.annotations.OnDelete) JoinTable(jakarta.persistence.JoinTable)

Example 3 with JoinTable

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

the class AnnotationBinder method bindManyToOne.

private static void bindManyToOne(PropertyHolder propertyHolder, PropertyData inferredData, boolean isIdentifierMapper, boolean inSecondPass, MetadataBuildingContext context, XProperty property, AnnotatedJoinColumn[] joinColumns, PropertyBinder propertyBinder, boolean forcePersist) {
    ManyToOne ann = property.getAnnotation(ManyToOne.class);
    // check validity
    if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
        throw new AnnotationException("@Column(s) not allowed on a @ManyToOne property: " + BinderHelper.getPath(propertyHolder, inferredData));
    }
    Cascade hibernateCascade = property.getAnnotation(Cascade.class);
    NotFound notFound = property.getAnnotation(NotFound.class);
    boolean ignoreNotFound = notFound != null && notFound.action() == NotFoundAction.IGNORE;
    matchIgnoreNotFoundWithFetchType(propertyHolder.getEntityName(), property.getName(), ignoreNotFound, ann.fetch());
    OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
    JoinTable assocTable = propertyHolder.getJoinTable(property);
    if (assocTable != null) {
        Join join = propertyHolder.addJoin(assocTable, false);
        for (AnnotatedJoinColumn joinColumn : joinColumns) {
            joinColumn.setExplicitTableName(join.getTable().getName());
        }
    }
    // MapsId means the columns belong to the pk;
    // A @MapsId association (obviously) must be non-null when the entity is first persisted.
    // If a @MapsId association is not mapped with @NotFound(IGNORE), then the association
    // is mandatory (even if the association has optional=true).
    // If a @MapsId association has optional=true and is mapped with @NotFound(IGNORE) then
    // the association is optional.
    final boolean mandatory = !ann.optional() || property.isAnnotationPresent(Id.class) || property.isAnnotationPresent(MapsId.class) && !ignoreNotFound;
    bindManyToOne(getCascadeStrategy(ann.cascade(), hibernateCascade, false, forcePersist), joinColumns, !mandatory, ignoreNotFound, onDeleteAnn != null && OnDeleteAction.CASCADE == onDeleteAnn.action(), ToOneBinder.getTargetEntity(inferredData, context), propertyHolder, inferredData, false, isIdentifierMapper, inSecondPass, propertyBinder, context);
}
Also used : MapKeyColumn(jakarta.persistence.MapKeyColumn) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) Column(jakarta.persistence.Column) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) OrderColumn(jakarta.persistence.OrderColumn) DiscriminatorColumn(jakarta.persistence.DiscriminatorColumn) AnnotatedDiscriminatorColumn.buildDiscriminatorColumn(org.hibernate.cfg.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn) AnnotatedJoinColumn.buildJoinTableJoinColumns(org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns) JoinColumns(jakarta.persistence.JoinColumns) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) Columns(org.hibernate.annotations.Columns) MapKeyJoinColumns(jakarta.persistence.MapKeyJoinColumns) AnnotationException(org.hibernate.AnnotationException) Join(org.hibernate.mapping.Join) ManyToOne(jakarta.persistence.ManyToOne) Cascade(org.hibernate.annotations.Cascade) NotFound(org.hibernate.annotations.NotFound) OnDelete(org.hibernate.annotations.OnDelete) JoinTable(jakarta.persistence.JoinTable)

Example 4 with JoinTable

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

the class AbstractPropertyHolder method buildHierarchyColumnOverride.

private void buildHierarchyColumnOverride(XClass element) {
    XClass current = element;
    Map<String, Column[]> columnOverride = new HashMap<>();
    Map<String, ColumnTransformer> columnTransformerOverride = new HashMap<>();
    Map<String, JoinColumn[]> joinColumnOverride = new HashMap<>();
    Map<String, JoinTable> joinTableOverride = new HashMap<>();
    Map<String, ForeignKey> foreignKeyOverride = new HashMap<>();
    while (current != null && !context.getBootstrapContext().getReflectionManager().toXClass(Object.class).equals(current)) {
        if (current.isAnnotationPresent(Entity.class) || current.isAnnotationPresent(MappedSuperclass.class) || current.isAnnotationPresent(Embeddable.class)) {
            // FIXME is embeddable override?
            Map<String, Column[]> currentOverride = buildColumnOverride(current, getPath());
            Map<String, ColumnTransformer> currentTransformerOverride = buildColumnTransformerOverride(current, getPath());
            Map<String, JoinColumn[]> currentJoinOverride = buildJoinColumnOverride(current, getPath());
            Map<String, JoinTable> currentJoinTableOverride = buildJoinTableOverride(current, getPath());
            Map<String, ForeignKey> currentForeignKeyOverride = buildForeignKeyOverride(current, getPath());
            // subclasses have precedence over superclasses
            currentOverride.putAll(columnOverride);
            // subclasses have precedence over superclasses
            currentTransformerOverride.putAll(columnTransformerOverride);
            // subclasses have precedence over superclasses
            currentJoinOverride.putAll(joinColumnOverride);
            // subclasses have precedence over superclasses
            currentJoinTableOverride.putAll(joinTableOverride);
            // subclasses have precedence over superclasses
            currentForeignKeyOverride.putAll(foreignKeyOverride);
            columnOverride = currentOverride;
            columnTransformerOverride = currentTransformerOverride;
            joinColumnOverride = currentJoinOverride;
            joinTableOverride = currentJoinTableOverride;
            foreignKeyOverride = currentForeignKeyOverride;
        }
        current = current.getSuperclass();
    }
    holderColumnOverride = columnOverride.size() > 0 ? columnOverride : null;
    holderColumnTransformerOverride = columnTransformerOverride.size() > 0 ? columnTransformerOverride : null;
    holderJoinColumnOverride = joinColumnOverride.size() > 0 ? joinColumnOverride : null;
    holderJoinTableOverride = joinTableOverride.size() > 0 ? joinTableOverride : null;
    holderForeignKeyOverride = foreignKeyOverride.size() > 0 ? foreignKeyOverride : null;
}
Also used : HashMap(java.util.HashMap) ForeignKey(jakarta.persistence.ForeignKey) XClass(org.hibernate.annotations.common.reflection.XClass) Embeddable(jakarta.persistence.Embeddable) ColumnTransformer(org.hibernate.annotations.ColumnTransformer) JoinTable(jakarta.persistence.JoinTable)

Example 5 with JoinTable

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

the class AbstractPropertyHolder method getJoinTable.

/**
 * Get column overriding, property first, then parent, then holder
 * replace the placeholder 'collection&&element' with nothing
 *
 * These rules are here to support both JPA 2 and legacy overriding rules.
 */
@Override
public JoinTable getJoinTable(XProperty property) {
    final String propertyName = StringHelper.qualify(getPath(), property.getName());
    JoinTable result = getOverriddenJoinTable(propertyName);
    if (result == null) {
        result = property.getAnnotation(JoinTable.class);
    }
    return result;
}
Also used : JoinTable(jakarta.persistence.JoinTable) AttributeOverride(jakarta.persistence.AttributeOverride) AssociationOverride(jakarta.persistence.AssociationOverride)

Aggregations

JoinTable (jakarta.persistence.JoinTable)23 JoinColumn (jakarta.persistence.JoinColumn)11 Test (org.junit.Test)9 MapKeyJoinColumn (jakarta.persistence.MapKeyJoinColumn)7 UniqueConstraint (jakarta.persistence.UniqueConstraint)6 PrimaryKeyJoinColumn (jakarta.persistence.PrimaryKeyJoinColumn)5 AnnotationException (org.hibernate.AnnotationException)5 OnDelete (org.hibernate.annotations.OnDelete)4 Join (org.hibernate.mapping.Join)4 AssociationOverride (jakarta.persistence.AssociationOverride)3 CollectionTable (jakarta.persistence.CollectionTable)3 JoinColumns (jakarta.persistence.JoinColumns)3 MapKeyJoinColumns (jakarta.persistence.MapKeyJoinColumns)3 PrimaryKeyJoinColumns (jakarta.persistence.PrimaryKeyJoinColumns)3 Cascade (org.hibernate.annotations.Cascade)3 FilterJoinTable (org.hibernate.annotations.FilterJoinTable)3 WhereJoinTable (org.hibernate.annotations.WhereJoinTable)3 AnnotatedJoinColumn (org.hibernate.cfg.AnnotatedJoinColumn)3 Column (jakarta.persistence.Column)2 DiscriminatorColumn (jakarta.persistence.DiscriminatorColumn)2