下面列出了怎么用org.hibernate.type.AssociationType的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Determine the appropriate associationType of join (if any) to use to fetch the
* given association.
*
* @param associationType The association associationType.
* @param config The metadata-defined fetch mode.
* @param path The path to the association
* @param lhsTable The owner table
* @param lhsColumns The owner join columns
* @param nullable Is the association nullable.
* @param currentDepth Current join depth
* @param cascadeStyle The metadata-defined cascade style.
*
* @return type of join to use ({@link org.hibernate.sql.JoinType#INNER_JOIN},
* {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN}, or -1 to indicate no joining.
*
* @throws MappingException ??
*/
protected JoinType getJoinType(
AssociationType associationType,
FetchMode config,
PropertyPath path,
String lhsTable,
String[] lhsColumns,
boolean nullable,
int currentDepth,
CascadeStyle cascadeStyle) throws MappingException {
if ( !isJoinedFetchEnabled( associationType, config, cascadeStyle ) ) {
return JoinType.NONE;
}
if ( isTooDeep( currentDepth ) || ( associationType.isCollectionType() && isTooManyCollections() ) ) {
return JoinType.NONE;
}
if ( isDuplicateAssociation( lhsTable, lhsColumns, associationType ) ) {
return JoinType.NONE;
}
return getJoinType( nullable, currentDepth );
}
/**
* Does the mapping, and Hibernate default semantics, specify that
* this association should be fetched by outer joining
*/
protected boolean isJoinedFetchEnabledInMapping(FetchMode config, AssociationType type)
throws MappingException {
if ( !type.isEntityType() && !type.isCollectionType() ) {
return false;
}
else {
if ( config == FetchMode.JOIN ) {
return true;
}
if ( config == FetchMode.SELECT ) {
return false;
}
if ( type.isEntityType() ) {
//TODO: look at the owning property and check that it
// isn't lazy (by instrumentation)
EntityType entityType = (EntityType) type;
EntityPersister persister = getFactory().getEntityPersister( entityType.getAssociatedEntityName() );
return !persister.hasProxy();
}
else {
return false;
}
}
}
/**
* Used to detect circularities in the joined graph, note that
* this method is side-effecty
*/
protected boolean isDuplicateAssociation(
final String lhsTable,
final String[] lhsColumnNames,
final AssociationType type) {
final String foreignKeyTable;
final String[] foreignKeyColumns;
if ( type.getForeignKeyDirection() == ForeignKeyDirection.FROM_PARENT ) {
foreignKeyTable = lhsTable;
foreignKeyColumns = lhsColumnNames;
}
else {
foreignKeyTable = type.getAssociatedJoinable( getFactory() ).getTableName();
foreignKeyColumns = JoinHelper.getRHSColumnNames( type, getFactory() );
}
return isDuplicateAssociation( foreignKeyTable, foreignKeyColumns );
}
/**
* Should we join this association?
*/
protected boolean isJoinable(
final JoinType joinType,
final Set visitedAssociationKeys,
final String lhsTable,
final String[] lhsColumnNames,
final AssociationType type,
final int depth) {
if ( joinType == JoinType.NONE ) {
return false;
}
if ( joinType == JoinType.INNER_JOIN ) {
return true;
}
Integer maxFetchDepth = getFactory().getSessionFactoryOptions().getMaximumFetchDepth();
final boolean tooDeep = maxFetchDepth != null && depth >= maxFetchDepth;
return !tooDeep && !isDuplicateAssociation( lhsTable, lhsColumnNames, type );
}
@Override
protected JoinType getJoinType(
AssociationType associationType,
FetchMode config,
PropertyPath path,
String lhsTable,
String[] lhsColumns,
boolean nullable,
int currentDepth,
CascadeStyle cascadeStyle) throws MappingException {
return getJoinType(
null,
path,
-1,
associationType,
config,
cascadeStyle,
lhsTable,
lhsColumns,
nullable,
currentDepth
);
}
public OuterJoinableAssociation(
PropertyPath propertyPath,
AssociationType joinableType,
String lhsAlias,
String[] lhsColumns,
String rhsAlias,
JoinType joinType,
String withClause,
boolean hasRestriction,
SessionFactoryImplementor factory,
Map enabledFilters) throws MappingException {
this.propertyPath = propertyPath;
this.joinableType = joinableType;
this.lhsAlias = lhsAlias;
this.lhsColumns = lhsColumns;
this.rhsAlias = rhsAlias;
this.joinType = joinType;
this.joinable = joinableType.getAssociatedJoinable( factory );
this.rhsColumns = JoinHelper.getRHSColumnNames( joinableType, factory );
this.on = joinableType.getOnCondition( rhsAlias, factory, enabledFilters )
+ ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" );
this.hasRestriction = hasRestriction;
this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application
}
private String resolveAdditionalJoinCondition(String rhsTableAlias, String withClause, Joinable joinable, AssociationType associationType) {
// turns out that the call to AssociationType#getOnCondition in the initial code really just translates to
// calls to the Joinable.filterFragment() method where the Joinable is either the entity or
// collection persister
final String filter = associationType!=null?
associationType.getOnCondition( rhsTableAlias, factory, queryInfluencers.getEnabledFilters() ):
joinable.filterFragment(
rhsTableAlias,
queryInfluencers.getEnabledFilters()
);
if ( StringHelper.isEmpty( withClause ) && StringHelper.isEmpty( filter ) ) {
return "";
}
else if ( StringHelper.isNotEmpty( withClause ) && StringHelper.isNotEmpty( filter ) ) {
return filter + " and " + withClause;
}
else {
// only one is non-empty...
return StringHelper.isNotEmpty( filter ) ? filter : withClause;
}
}
/**
* Get the join type (inner, outer, etc) or -1 if the
* association should not be joined. Override on
* subclasses.
*/
protected int getJoinType(
AssociationType type,
FetchMode config,
String path,
String lhsTable,
String[] lhsColumns,
boolean nullable,
int currentDepth,
CascadeStyle cascadeStyle)
throws MappingException {
if ( !isJoinedFetchEnabled(type, config, cascadeStyle) ) return -1;
if ( isTooDeep(currentDepth) || ( type.isCollectionType() && isTooManyCollections() ) ) return -1;
final boolean dupe = isDuplicateAssociation(lhsTable, lhsColumns, type);
if (dupe) return -1;
return getJoinType(nullable, currentDepth);
}
private String getPathEntityName(String path) {
Queryable persister = ( Queryable ) sessionFactory.getEntityPersister( rootEntityName );
StringTokenizer tokens = new StringTokenizer( path, "." );
String componentPath = "";
while ( tokens.hasMoreTokens() ) {
componentPath += tokens.nextToken();
Type type = persister.toType( componentPath );
if ( type.isAssociationType() ) {
AssociationType atype = ( AssociationType ) type;
persister = ( Queryable ) sessionFactory.getEntityPersister(
atype.getAssociatedEntityName( sessionFactory )
);
componentPath = "";
}
else if ( type.isComponentType() ) {
componentPath += '.';
}
else {
throw new QueryException( "not an association: " + componentPath );
}
}
return persister.getEntityName();
}
/**
* Add on association (one-to-one, many-to-one, or a collection) to a list
* of associations to be fetched by outerjoin (if necessary)
*/
private void addAssociationToJoinTreeIfNecessary(
final AssociationType type,
final String[] aliasedLhsColumns,
final String alias,
final String path,
int currentDepth,
final int joinType)
throws MappingException {
if (joinType>=0) {
addAssociationToJoinTree(
type,
aliasedLhsColumns,
alias,
path,
currentDepth,
joinType
);
}
}
/**
* 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 );
}
}
}
protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException {
FromElement fromElement = currentFromClause.addFromElement( filterEntity.getText(), alias );
FromClause fromClause = fromElement.getFromClause();
QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole );
// Get the names of the columns used to link between the collection
// owner and the collection elements.
String[] keyColumnNames = persister.getKeyColumnNames();
String fkTableAlias = persister.isOneToMany()
? fromElement.getTableAlias()
: fromClause.getAliasGenerator().createName( collectionFilterRole );
JoinSequence join = sessionFactoryHelper.createJoinSequence();
join.setRoot( persister, fkTableAlias );
if ( !persister.isOneToMany() ) {
join.addJoin( ( AssociationType ) persister.getElementType(),
fromElement.getTableAlias(),
JoinFragment.INNER_JOIN,
persister.getElementColumnNames( fkTableAlias ) );
}
join.addCondition( fkTableAlias, keyColumnNames, " = ?" );
fromElement.setJoinSequence( join );
fromElement.setFilter( true );
if ( log.isDebugEnabled() ) {
log.debug( "createFromFilterElement() : processed filter FROM element." );
}
return fromElement;
}
/**
* Get the aliased columns of the owning entity which are to
* be used in the join
*/
public static String[] getAliasedLHSColumnNames(
AssociationType type,
String alias,
int property,
int begin,
OuterJoinLoadable lhsPersister,
Mapping mapping
) {
if ( type.useLHSPrimaryKey() ) {
return StringHelper.qualify( alias, lhsPersister.getIdentifierColumnNames() );
}
else {
String propertyName = type.getLHSPropertyName();
if (propertyName==null) {
return ArrayHelper.slice(
lhsPersister.toColumns(alias, property),
begin,
type.getColumnSpan(mapping)
);
}
else {
return ( (PropertyMapping) lhsPersister ).toColumns(alias, propertyName); //bad cast
}
}
}
@Override
public void registerJoinAlias(Tree aliasNode, PropertyPath path) {
String alias = aliasNode.getText();
Type type = propertyHelper.getPropertyType(
propertyHelper.getEntityNameByAlias( path.getFirstNode().getName() ),
path.getNodeNamesWithoutAlias() );
if ( type.isEntityType() ) {
propertyHelper.registerEntityAlias( type.getName(), alias );
}
else if ( type.isAssociationType() ) {
propertyHelper.registerEntityAlias(
( (AssociationType) type ).getAssociatedEntityName( sessionFactory ), alias );
}
else {
throw new IllegalArgumentException( "Failed to determine type for alias '" + alias + "'" );
}
}
/**
* For an entity class, add to a list of associations to be fetched
* by outerjoin
*/
private final void walkEntityTree(
final OuterJoinLoadable persister,
final String alias,
final String path,
final int currentDepth)
throws MappingException {
int n = persister.countSubclassProperties();
for ( int i=0; i<n; i++ ) {
Type type = persister.getSubclassPropertyType(i);
if ( type.isAssociationType() ) {
walkEntityAssociationTree(
(AssociationType) type,
persister,
i,
alias,
path,
persister.isSubclassPropertyNullable(i),
currentDepth
);
}
else if ( type.isComponentType() ) {
walkComponentTree(
(AbstractComponentType) type,
i,
0,
persister,
alias,
subPath( path, persister.getSubclassPropertyName(i) ),
currentDepth
);
}
}
}
Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
public String addFromCollection(QueryTranslatorImpl q) throws QueryException {
Type collectionElementType = getPropertyType();
if ( collectionElementType == null ) {
throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path );
}
if ( collectionElementType.isEntityType() ) {
// an association
QueryableCollection collectionPersister = q.getCollectionPersister( collectionRole );
Queryable entityPersister = ( Queryable ) collectionPersister.getElementPersister();
String clazz = entityPersister.getEntityName();
final String elementName;
if ( collectionPersister.isOneToMany() ) {
elementName = collectionName;
//allow index() function:
q.decoratePropertyMapping( elementName, collectionPersister );
}
else { //many-to-many
q.addCollection( collectionName, collectionRole );
elementName = q.createNameFor( clazz );
addJoin( elementName, ( AssociationType ) collectionElementType );
}
q.addFrom( elementName, clazz, joinSequence );
currentPropertyMapping = new CollectionPropertyMapping( collectionPersister );
return elementName;
}
else {
// collections of values
q.addFromCollection( collectionName, collectionRole, joinSequence );
return collectionName;
}
}
/**
* Process a particular association owned by the entity
*
* @param associationType The type representing the association to be
* processed.
* @param persister The owner of the association to be processed.
* @param propertyNumber The property number for the association
* (relative to the persister).
* @param alias The entity alias
* @param path The path to the association
* @param nullable is the association nullable (which I think is supposed
* to indicate inner/outer join semantics).
* @param currentDepth The current join depth
*
* @throws org.hibernate.MappingException ???
*/
private void walkEntityAssociationTree(
final AssociationType associationType,
final OuterJoinLoadable persister,
final int propertyNumber,
final String alias,
final PropertyPath path,
final boolean nullable,
final int currentDepth) throws MappingException {
String[] aliasedLhsColumns = JoinHelper.getAliasedLHSColumnNames(
associationType, alias, propertyNumber, persister, getFactory()
);
String[] lhsColumns = JoinHelper.getLHSColumnNames(
associationType, propertyNumber, persister, getFactory()
);
String lhsTable = JoinHelper.getLHSTableName( associationType, propertyNumber, persister );
PropertyPath subPath = path.append( persister.getSubclassPropertyName( propertyNumber ) );
JoinType joinType = getJoinType(
persister,
subPath,
propertyNumber,
associationType,
persister.getFetchMode( propertyNumber ),
persister.getCascadeStyle( propertyNumber ),
lhsTable,
lhsColumns,
nullable,
currentDepth
);
addAssociationToJoinTreeIfNecessary(
associationType,
aliasedLhsColumns,
alias,
subPath,
currentDepth,
joinType
);
}
protected JoinType getJoinType(
OuterJoinLoadable persister,
PropertyPath path,
int propertyNumber,
AssociationType associationType,
FetchMode metadataFetchMode,
CascadeStyle metadataCascadeStyle,
String lhsTable,
String[] lhsColumns,
boolean nullable,
int currentDepth) throws MappingException {
JoinType joinType = super.getJoinType(
persister,
path,
propertyNumber,
associationType,
metadataFetchMode,
metadataCascadeStyle,
lhsTable,
lhsColumns,
nullable,
currentDepth
);
//we can use an inner join for the many-to-many
if ( joinType==JoinType.LEFT_OUTER_JOIN && path.isRoot() ) {
joinType=JoinType.INNER_JOIN;
}
return joinType;
}
/**
* Used for collection filters
*/
private void addFromAssociation(final String elementName, final String collectionRole)
throws QueryException {
//q.addCollection(collectionName, collectionRole);
QueryableCollection persister = getCollectionPersister( collectionRole );
Type collectionElementType = persister.getElementType();
if ( !collectionElementType.isEntityType() ) {
throw new QueryException( "collection of values in filter: " + elementName );
}
String[] keyColumnNames = persister.getKeyColumnNames();
//if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole);
String collectionName;
JoinSequence join = new JoinSequence( getFactory() );
collectionName = persister.isOneToMany() ?
elementName :
createNameForCollection( collectionRole );
join.setRoot( persister, collectionName );
if ( !persister.isOneToMany() ) {
//many-to-many
addCollection( collectionName, collectionRole );
try {
join.addJoin( ( AssociationType ) persister.getElementType(),
elementName,
JoinFragment.INNER_JOIN,
persister.getElementColumnNames(collectionName) );
}
catch ( MappingException me ) {
throw new QueryException( me );
}
}
join.addCondition( collectionName, keyColumnNames, " = ?" );
//if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
EntityType elemType = ( EntityType ) collectionElementType;
addFrom( elementName, elemType.getAssociatedEntityName(), join );
}
Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
public EntityBasedAssociationAttribute(
EntityPersister source,
SessionFactoryImplementor sessionFactory,
int attributeNumber,
String attributeName,
AssociationType attributeType,
BaselineAttributeInformation baselineInfo) {
super( source, sessionFactory, attributeNumber, attributeName, attributeType, baselineInfo );
}
private static EntityPersister resolveEntityPersister(
Object entity,
AssociationType associationType,
SharedSessionContractImplementor session,
SessionFactoryImplementor sessionFactory) {
assert sessionFactory != null;
if ( session != null ) {
return session.getEntityPersister(
associationType.getAssociatedEntityName( session.getFactory() ),
entity
);
}
String entityName = null;
for ( EntityNameResolver entityNameResolver : sessionFactory.getMetamodel().getEntityNameResolvers() ) {
entityName = entityNameResolver.resolveEntityName( entity );
if ( entityName != null ) {
break;
}
}
if ( entityName == null ) {
// old fall-back
entityName = entity.getClass().getName();
}
return sessionFactory.getMetamodel().entityPersister( entityName );
}
public CompositeBasedAssociationAttribute(
AbstractCompositionAttribute source,
SessionFactoryImplementor factory,
int entityBasedAttributeNumber,
String attributeName,
AssociationType attributeType,
BaselineAttributeInformation baselineInfo,
int subAttributeNumber,
AssociationKey associationKey) {
super( source, factory, entityBasedAttributeNumber, attributeName, attributeType, baselineInfo );
this.subAttributeNumber = subAttributeNumber;
this.associationKey = associationKey;
}
/**
* Get the columns of the owning entity which are to
* be used in 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 {
String propertyName = type.getLHSPropertyName();
if (propertyName==null) {
//slice, to get the columns for this component
//property
return ArrayHelper.slice(
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);
}
}
}
Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
Join(
SessionFactoryImplementor factory,
AssociationType associationType,
String alias,
JoinType joinType,
String[][] lhsColumns) throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}