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);
}
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);
}
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);
}
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;
}
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;
}
Aggregations