Java tutorial
/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.engine.internal; import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.entity.PropertyMapping; import org.hibernate.type.AssociationType; /** * Helper for dealing with joins. * * @author Gavin King */ public final class JoinHelper { /** * Get the qualified (prefixed by alias) names of the columns of the owning entity which are to be used in the join * * @param type The association type for the association that represents the join * @param alias The left-hand side table alias * @param property The index of the property that represents the association/join * @param lhsPersister The persister for the left-hand side of the association/join * @param mapping The mapping (typically the SessionFactory). * * @return The qualified column names. */ public static String[] getAliasedLHSColumnNames(AssociationType type, String alias, int property, OuterJoinLoadable lhsPersister, Mapping mapping) { return getAliasedLHSColumnNames(type, alias, property, 0, lhsPersister, mapping); } /** * Get the unqualified names of the columns of the owning entity which are to be used in the join. * * @param type The association type for the association that represents the join * @param property The name of the property that represents the association/join * @param lhsPersister The persister for the left-hand side of the association/join * @param mapping The mapping (typically the SessionFactory). * * @return The unqualified column names. */ public static String[] getLHSColumnNames(AssociationType type, int property, OuterJoinLoadable lhsPersister, Mapping mapping) { return getLHSColumnNames(type, property, 0, lhsPersister, mapping); } /** * */ /** * Get the qualified (prefixed by alias) names of the columns of the owning entity which are to be used in the join * * @param associationType The association type for the association that represents the join * @param columnQualifier The left-hand side table alias * @param propertyIndex The index of the property that represents the association/join * @param begin The index for any nested (composites) attributes * @param lhsPersister The persister for the left-hand side of the association/join * @param mapping The mapping (typically the SessionFactory). * * @return The qualified column names. */ public static String[] getAliasedLHSColumnNames(AssociationType associationType, String columnQualifier, int propertyIndex, int begin, OuterJoinLoadable lhsPersister, Mapping mapping) { if (associationType.useLHSPrimaryKey()) { return StringHelper.qualify(columnQualifier, lhsPersister.getIdentifierColumnNames()); } else { final String propertyName = associationType.getLHSPropertyName(); if (propertyName == null) { return ArrayHelper.slice(toColumns(lhsPersister, columnQualifier, propertyIndex), begin, associationType.getColumnSpan(mapping)); } else { //bad cast return ((PropertyMapping) lhsPersister).toColumns(columnQualifier, propertyName); } } } private static String[] toColumns(OuterJoinLoadable persister, String columnQualifier, int propertyIndex) { if (propertyIndex >= 0) { return persister.toColumns(columnQualifier, propertyIndex); } else { final String[] cols = persister.getIdentifierColumnNames(); final String[] result = new String[cols.length]; for (int j = 0; j < cols.length; j++) { result[j] = StringHelper.qualify(columnQualifier, cols[j]); } return result; } } /** * Get the columns of the owning entity which are to be used in the join * * @param type The type representing the join * @param property The property index for the association type * @param begin ? * @param lhsPersister The persister for the left-hand-side of the join * @param mapping The mapping object (typically the SessionFactory) * * @return The columns for the left-hand-side of the join */ public static String[] getLHSColumnNames(AssociationType type, int property, int begin, OuterJoinLoadable lhsPersister, Mapping mapping) { if (type.useLHSPrimaryKey()) { //return lhsPersister.getSubclassPropertyColumnNames(property); return lhsPersister.getIdentifierColumnNames(); } else { final String propertyName = type.getLHSPropertyName(); if (propertyName == null) { //slice, to get the columns for this component //property return ArrayHelper.slice( property < 0 ? lhsPersister.getIdentifierColumnNames() : lhsPersister.getSubclassPropertyColumnNames(property), begin, type.getColumnSpan(mapping)); } else { //property-refs for associations defined on a //component are not supported, so no need to slice return lhsPersister.getPropertyColumnNames(propertyName); } } } /** * Determine the name of the table that is the left-hand-side of the join. Usually this is the * name of the main table from the left-hand-side persister. But that is not the case with property-refs. * * @param type The type representing the join * @param propertyIndex The property index for the type * @param lhsPersister The persister for the left-hand-side of the join * * @return The table name */ public static String getLHSTableName(AssociationType type, int propertyIndex, OuterJoinLoadable lhsPersister) { if (type.useLHSPrimaryKey() || propertyIndex < 0) { return lhsPersister.getTableName(); } else { final String propertyName = type.getLHSPropertyName(); if (propertyName == null) { //if there is no property-ref, assume the join //is to the subclass table (ie. the table of the //subclass that the association belongs to) return lhsPersister.getSubclassPropertyTableName(propertyIndex); } else { //handle a property-ref String propertyRefTable = lhsPersister.getPropertyTableName(propertyName); if (propertyRefTable == null) { //it is possible that the tree-walking in OuterJoinLoader can get to //an association defined by a subclass, in which case the property-ref //might refer to a property defined on a subclass of the current class //in this case, the table name is not known - this temporary solution //assumes that the property-ref refers to a property of the subclass //table that the association belongs to (a reasonable guess) //TODO: fix this, add: OuterJoinLoadable.getSubclassPropertyTableName(String propertyName) propertyRefTable = lhsPersister.getSubclassPropertyTableName(propertyIndex); } return propertyRefTable; } } } /** * Get the columns of the associated table which are to be used in the join * * @param type The type * @param factory The SessionFactory * * @return The columns for the right-hand-side of the join */ public static String[] getRHSColumnNames(AssociationType type, SessionFactoryImplementor factory) { final String uniqueKeyPropertyName = type.getRHSUniqueKeyPropertyName(); final Joinable joinable = type.getAssociatedJoinable(factory); if (uniqueKeyPropertyName == null) { return joinable.getKeyColumnNames(); } else { return ((OuterJoinLoadable) joinable).getPropertyColumnNames(uniqueKeyPropertyName); } } private JoinHelper() { } }