use of org.hibernate.mapping.Join in project hibernate-orm by hibernate.
the class ClassPropertyHolder method addProperty.
public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
//Ejb3Column.checkPropertyConsistency( ); //already called earlier
if (columns != null && columns[0].isSecondary()) {
//TODO move the getJoin() code here?
final Join join = columns[0].getJoin();
addPropertyToJoin(prop, declaringClass, join);
} else {
addProperty(prop, declaringClass);
}
}
use of org.hibernate.mapping.Join in project hibernate-orm by hibernate.
the class EntityBinder method finalSecondaryTableBinding.
public void finalSecondaryTableBinding(PropertyHolder propertyHolder) {
/*
* Those operations has to be done afterQuery the id definition of the persistence class.
* ie afterQuery the properties parsing
*/
Iterator joins = secondaryTables.values().iterator();
Iterator joinColumns = secondaryTableJoins.values().iterator();
while (joins.hasNext()) {
Object uncastedColumn = joinColumns.next();
Join join = (Join) joins.next();
createPrimaryColumnsToSecondaryTable(uncastedColumn, propertyHolder, join);
}
}
use of org.hibernate.mapping.Join in project hibernate-orm by hibernate.
the class EntityBinder method addJoin.
private Join addJoin(SecondaryTable secondaryTable, JoinTable joinTable, PropertyHolder propertyHolder, boolean noDelayInPkColumnCreation) {
// A non null propertyHolder means than we process the Pk creation without delay
Join join = new Join();
join.setPersistentClass(persistentClass);
final String schema;
final String catalog;
final SecondaryTableNameSource secondaryTableNameContext;
final Object joinColumns;
final List<UniqueConstraintHolder> uniqueConstraintHolders;
final Identifier logicalName;
if (secondaryTable != null) {
schema = secondaryTable.schema();
catalog = secondaryTable.catalog();
logicalName = context.getMetadataCollector().getDatabase().getJdbcEnvironment().getIdentifierHelper().toIdentifier(secondaryTable.name());
joinColumns = secondaryTable.pkJoinColumns();
uniqueConstraintHolders = TableBinder.buildUniqueConstraintHolders(secondaryTable.uniqueConstraints());
} else if (joinTable != null) {
schema = joinTable.schema();
catalog = joinTable.catalog();
logicalName = context.getMetadataCollector().getDatabase().getJdbcEnvironment().getIdentifierHelper().toIdentifier(joinTable.name());
joinColumns = joinTable.joinColumns();
uniqueConstraintHolders = TableBinder.buildUniqueConstraintHolders(joinTable.uniqueConstraints());
} else {
throw new AssertionFailure("Both JoinTable and SecondaryTable are null");
}
final Table table = TableBinder.buildAndFillTable(schema, catalog, logicalName, false, uniqueConstraintHolders, null, null, context, null, null);
final InFlightMetadataCollector.EntityTableXref tableXref = context.getMetadataCollector().getEntityTableXref(persistentClass.getEntityName());
assert tableXref != null : "Could not locate EntityTableXref for entity [" + persistentClass.getEntityName() + "]";
tableXref.addSecondaryTable(logicalName, join);
if (secondaryTable != null) {
TableBinder.addIndexes(table, secondaryTable.indexes(), context);
}
//no check constraints available on joins
join.setTable(table);
//somehow keep joins() for later.
//Has to do the work later because it needs persistentClass id!
LOG.debugf("Adding secondary table to entity %s -> %s", persistentClass.getEntityName(), join.getTable().getName());
org.hibernate.annotations.Table matchingTable = findMatchingComplimentTableAnnotation(join);
if (matchingTable != null) {
join.setSequentialSelect(FetchMode.JOIN != matchingTable.fetch());
join.setInverse(matchingTable.inverse());
join.setOptional(matchingTable.optional());
if (!BinderHelper.isEmptyAnnotationValue(matchingTable.sqlInsert().sql())) {
join.setCustomSQLInsert(matchingTable.sqlInsert().sql().trim(), matchingTable.sqlInsert().callable(), ExecuteUpdateResultCheckStyle.fromExternalName(matchingTable.sqlInsert().check().toString().toLowerCase(Locale.ROOT)));
}
if (!BinderHelper.isEmptyAnnotationValue(matchingTable.sqlUpdate().sql())) {
join.setCustomSQLUpdate(matchingTable.sqlUpdate().sql().trim(), matchingTable.sqlUpdate().callable(), ExecuteUpdateResultCheckStyle.fromExternalName(matchingTable.sqlUpdate().check().toString().toLowerCase(Locale.ROOT)));
}
if (!BinderHelper.isEmptyAnnotationValue(matchingTable.sqlDelete().sql())) {
join.setCustomSQLDelete(matchingTable.sqlDelete().sql().trim(), matchingTable.sqlDelete().callable(), ExecuteUpdateResultCheckStyle.fromExternalName(matchingTable.sqlDelete().check().toString().toLowerCase(Locale.ROOT)));
}
} else {
//default
join.setSequentialSelect(false);
join.setInverse(false);
//perhaps not quite per-spec, but a Good Thing anyway
join.setOptional(true);
}
if (noDelayInPkColumnCreation) {
createPrimaryColumnsToSecondaryTable(joinColumns, propertyHolder, join);
} else {
secondaryTables.put(table.getQuotedName(), join);
secondaryTableJoins.put(table.getQuotedName(), joinColumns);
}
return join;
}
use of org.hibernate.mapping.Join in project hibernate-orm by hibernate.
the class OneToOneSecondPass method doSecondPass.
//TODO refactor this code, there is a lot of duplication in this method
public void doSecondPass(Map persistentClasses) throws MappingException {
org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne(buildingContext.getMetadataCollector(), propertyHolder.getTable(), propertyHolder.getPersistentClass());
final String propertyName = inferredData.getPropertyName();
value.setPropertyName(propertyName);
String referencedEntityName = ToOneBinder.getReferenceEntityName(inferredData, targetEntity, buildingContext);
value.setReferencedEntityName(referencedEntityName);
AnnotationBinder.defineFetchingStrategy(value, inferredData.getProperty());
//value.setFetchMode( fetchMode );
value.setCascadeDeleteEnabled(cascadeOnDelete);
if (!optional)
value.setConstrained(true);
value.setForeignKeyType(value.isConstrained() ? ForeignKeyDirection.FROM_PARENT : ForeignKeyDirection.TO_PARENT);
PropertyBinder binder = new PropertyBinder();
binder.setName(propertyName);
binder.setValue(value);
binder.setCascade(cascadeStrategy);
binder.setAccessType(inferredData.getDefaultAccess());
Property prop = binder.makeProperty();
if (ignoreNotFound) {
prop.setOptional(true);
}
if (BinderHelper.isEmptyAnnotationValue(mappedBy)) {
/*
* we need to check if the columns are in the right order
* if not, then we need to create a many to one and formula
* but actually, since entities linked by a one to one need
* to share the same composite id class, this cannot happen in hibernate
*/
boolean rightOrder = true;
if (rightOrder) {
String path = StringHelper.qualify(propertyHolder.getPath(), propertyName);
final ToOneFkSecondPass secondPass = new ToOneFkSecondPass(value, joinColumns, //cannot have nullabe and unique on certain DBs
!optional, propertyHolder.getEntityOwnerClassName(), path, buildingContext);
secondPass.doSecondPass(persistentClasses);
//no column associated since its a one to one
propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
} else {
//this is a many to one with Formula
}
} else {
PersistentClass otherSide = (PersistentClass) persistentClasses.get(value.getReferencedEntityName());
Property otherSideProperty;
try {
if (otherSide == null) {
throw new MappingException("Unable to find entity: " + value.getReferencedEntityName());
}
otherSideProperty = BinderHelper.findPropertyByName(otherSide, mappedBy);
} catch (MappingException e) {
throw new AnnotationException("Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
}
if (otherSideProperty == null) {
throw new AnnotationException("Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
}
if (otherSideProperty.getValue() instanceof OneToOne) {
propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
} else if (otherSideProperty.getValue() instanceof ManyToOne) {
Iterator it = otherSide.getJoinIterator();
Join otherSideJoin = null;
while (it.hasNext()) {
Join otherSideJoinValue = (Join) it.next();
if (otherSideJoinValue.containsProperty(otherSideProperty)) {
otherSideJoin = otherSideJoinValue;
break;
}
}
if (otherSideJoin != null) {
//@OneToOne @JoinTable
Join mappedByJoin = buildJoinFromMappedBySide((PersistentClass) persistentClasses.get(ownerEntity), otherSideProperty, otherSideJoin);
ManyToOne manyToOne = new ManyToOne(buildingContext.getMetadataCollector(), mappedByJoin.getTable());
//FIXME use ignore not found here
manyToOne.setIgnoreNotFound(ignoreNotFound);
manyToOne.setCascadeDeleteEnabled(value.isCascadeDeleteEnabled());
manyToOne.setFetchMode(value.getFetchMode());
manyToOne.setLazy(value.isLazy());
manyToOne.setReferencedEntityName(value.getReferencedEntityName());
manyToOne.setUnwrapProxy(value.isUnwrapProxy());
prop.setValue(manyToOne);
Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator();
while (otherSideJoinKeyColumns.hasNext()) {
Column column = (Column) otherSideJoinKeyColumns.next();
Column copy = new Column();
copy.setLength(column.getLength());
copy.setScale(column.getScale());
copy.setValue(manyToOne);
copy.setName(column.getQuotedName());
copy.setNullable(column.isNullable());
copy.setPrecision(column.getPrecision());
copy.setUnique(column.isUnique());
copy.setSqlType(column.getSqlType());
copy.setCheckConstraint(column.getCheckConstraint());
copy.setComment(column.getComment());
copy.setDefaultValue(column.getDefaultValue());
manyToOne.addColumn(copy);
}
mappedByJoin.addProperty(prop);
} else {
propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
}
value.setReferencedPropertyName(mappedBy);
// HHH-6813
// Foo: @Id long id, @OneToOne(mappedBy="foo") Bar bar
// Bar: @Id @OneToOne Foo foo
boolean referencesDerivedId = false;
try {
referencesDerivedId = otherSide.getIdentifier() instanceof Component && ((Component) otherSide.getIdentifier()).getProperty(mappedBy) != null;
} catch (MappingException e) {
// ignore
}
boolean referenceToPrimaryKey = referencesDerivedId || mappedBy == null;
value.setReferenceToPrimaryKey(referenceToPrimaryKey);
// loop of attempts to resolve identifiers.
if (referencesDerivedId) {
((ManyToOne) otherSideProperty.getValue()).setReferenceToPrimaryKey(false);
}
String propertyRef = value.getReferencedPropertyName();
if (propertyRef != null) {
buildingContext.getMetadataCollector().addUniquePropertyReference(value.getReferencedEntityName(), propertyRef);
}
} else {
throw new AnnotationException("Referenced property not a (One|Many)ToOne: " + StringHelper.qualify(otherSide.getEntityName(), mappedBy) + " in mappedBy of " + StringHelper.qualify(ownerEntity, ownerProperty));
}
}
final ForeignKey fk = inferredData.getProperty().getAnnotation(ForeignKey.class);
if (fk != null && !BinderHelper.isEmptyAnnotationValue(fk.name())) {
value.setForeignKeyName(fk.name());
} else {
final javax.persistence.ForeignKey jpaFk = inferredData.getProperty().getAnnotation(javax.persistence.ForeignKey.class);
if (jpaFk != null) {
if (jpaFk.value() == ConstraintMode.NO_CONSTRAINT) {
value.setForeignKeyName("none");
} else {
value.setForeignKeyName(StringHelper.nullIfEmpty(jpaFk.name()));
value.setForeignKeyDefinition(StringHelper.nullIfEmpty(jpaFk.foreignKeyDefinition()));
}
}
}
}
use of org.hibernate.mapping.Join in project hibernate-orm by hibernate.
the class JoinedSubclassEntityPersister method associateSubclassNamesToSubclassTableIndexes.
private void associateSubclassNamesToSubclassTableIndexes(PersistentClass persistentClass, Set<String> classNames, String[][] mapping, SessionFactoryImplementor factory) {
final String tableName = persistentClass.getTable().getQualifiedName(factory.getDialect(), factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName());
associateSubclassNamesToSubclassTableIndex(tableName, classNames, mapping);
Iterator itr = persistentClass.getJoinIterator();
while (itr.hasNext()) {
final Join join = (Join) itr.next();
final String secondaryTableName = join.getTable().getQualifiedName(factory.getDialect(), factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName());
associateSubclassNamesToSubclassTableIndex(secondaryTableName, classNames, mapping);
}
}
Aggregations