下面列出了怎么用org.hibernate.persister.entity.Joinable的API类实例代码及写法,或者点击链接到github查看源代码。
private void renderEntityJoin(Join join, JoinFragment joinFragment) {
final EntityQuerySpace rightHandSide = (EntityQuerySpace) join.getRightHandSide();
// see if there is already aliases registered for this entity query space (collection joins)
EntityReferenceAliases aliases = aliasResolutionContext.resolveEntityReferenceAliases( rightHandSide.getUid() );
if ( aliases == null && mutableAliasResolutionContext != null ) {
mutableAliasResolutionContext.generateEntityReferenceAliases(
rightHandSide.getUid(),
rightHandSide.getEntityPersister()
);
}
final Joinable joinable = (Joinable) rightHandSide.getEntityPersister();
addJoins(
join,
joinFragment,
joinable,
null
);
}
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;
}
}
public String selectFragment(
Joinable rhs,
String rhsAlias,
String lhsAlias,
String entitySuffix,
String collectionSuffix,
boolean includeCollectionColumns) {
StringBuilder buf = new StringBuilder();
if ( includeCollectionColumns ) {
// buf.append( selectFragment( lhsAlias, "" ) )//ignore suffix for collection columns!
buf.append( selectFragment( lhsAlias, collectionSuffix ) )
.append( ", " );
}
OuterJoinLoadable ojl = (OuterJoinLoadable) getElementPersister();
return buf.append( ojl.selectFragment( lhsAlias, entitySuffix ) )//use suffix for the entity columns
.toString();
}
public String selectFragment(
Joinable rhs,
String rhsAlias,
String lhsAlias,
String entitySuffix,
String collectionSuffix,
boolean includeCollectionColumns) {
StringBuffer buf = new StringBuffer();
if ( includeCollectionColumns ) {
// buf.append( selectFragment( lhsAlias, "" ) )//ignore suffix for collection columns!
buf.append( selectFragment( lhsAlias, collectionSuffix ) )
.append( ", " );
}
OuterJoinLoadable ojl = ( OuterJoinLoadable ) getElementPersister();
return buf.append( ojl.selectFragment( lhsAlias, entitySuffix ) )//use suffix for the entity columns
.toString();
}
public String selectFragment(
Joinable rhs,
String rhsAlias,
String lhsAlias,
String entitySuffix,
String collectionSuffix,
boolean includeCollectionColumns) {
// we need to determine the best way to know that two joinables
// represent a single many-to-many...
if ( rhs != null && isManyToMany() && !rhs.isCollection() ) {
AssociationType elementType = ( ( AssociationType ) getElementType() );
if ( rhs.equals( elementType.getAssociatedJoinable( getFactory() ) ) ) {
return manyToManySelectFragment( rhs, rhsAlias, lhsAlias, collectionSuffix );
}
}
return includeCollectionColumns ? selectFragment( lhsAlias, collectionSuffix ) : "";
}
public JoinSequence getJoinSequence() {
if ( joinSequence != null ) {
return joinSequence;
}
// Class names in the FROM clause result in a JoinSequence (the old FromParser does this).
if ( persister instanceof Joinable ) {
Joinable joinable = ( Joinable ) persister;
return fromElement.getSessionFactoryHelper().createJoinSequence().setRoot( joinable, getTableAlias() );
}
else {
return null; // TODO: Should this really return null? If not, figure out something better to do here.
}
}
protected void applyRootReturnWhereJoinRestrictions(SelectStatementBuilder selectStatementBuilder) {
final Joinable joinable = (OuterJoinLoadable) getRootEntityReturn().getEntityPersister();
selectStatementBuilder.appendRestrictions(
joinable.whereJoinFragment(
entityReferenceAliases.getTableAlias(),
true,
true
)
);
}
/**
* Get the columns of the associated table which are to
* be used in the join
*/
public static String[] getRHSColumnNames(AssociationType type, SessionFactoryImplementor factory) {
String uniqueKeyPropertyName = type.getRHSUniqueKeyPropertyName();
Joinable joinable = type.getAssociatedJoinable(factory);
if (uniqueKeyPropertyName==null) {
return joinable.getKeyColumnNames();
}
else {
return ( (OuterJoinLoadable) joinable ).getPropertyColumnNames(uniqueKeyPropertyName);
}
}
@Override
public void startingEntity(EntityDefinition entityDefinition) {
// see if the EntityDefinition is a root...
final boolean isRoot = fetchSourceStack.isEmpty();
if ( ! isRoot ) {
// if not, this call should represent a fetch which should have been handled in #startingAttribute
return;
}
// if we get here, it is a root
log.tracef(
"%s Starting root entity : %s",
StringHelper.repeat( ">>", fetchSourceStack.size() ),
entityDefinition.getEntityPersister().getEntityName()
);
if ( !supportsRootEntityReturns() ) {
throw new HibernateException( "This strategy does not support root entity returns" );
}
final EntityReturnImpl entityReturn = new EntityReturnImpl( entityDefinition, querySpaces );
addRootReturn( entityReturn );
pushToStack( entityReturn );
// also add an AssociationKey for the root so we can later on recognize circular references back to the root.
final Joinable entityPersister = (Joinable) entityDefinition.getEntityPersister();
associationKeyRegistered(
new AssociationKey( entityPersister.getTableName(), entityPersister.getKeyColumnNames() )
);
}
@Override
public void startingCollection(CollectionDefinition collectionDefinition) {
// see if the EntityDefinition is a root...
final boolean isRoot = fetchSourceStack.isEmpty();
if ( ! isRoot ) {
// if not, this call should represent a fetch which should have been handled in #startingAttribute
return;
}
log.tracef(
"%s Starting root collection : %s",
StringHelper.repeat( ">>", fetchSourceStack.size() ),
collectionDefinition.getCollectionPersister().getRole()
);
// if we get here, it is a root
if ( ! supportsRootCollectionReturns() ) {
throw new HibernateException( "This strategy does not support root collection returns" );
}
final CollectionReturn collectionReturn = new CollectionReturnImpl( collectionDefinition, querySpaces );
pushToCollectionStack( collectionReturn );
addRootReturn( collectionReturn );
associationKeyRegistered(
new AssociationKey(
( (Joinable) collectionDefinition.getCollectionPersister() ).getTableName(),
( (Joinable) collectionDefinition.getCollectionPersister() ).getKeyColumnNames()
)
);
}
@Override
public void foundCircularAssociation(AssociationAttributeDefinition attributeDefinition) {
final FetchStrategy fetchStrategy = determineFetchStrategy( attributeDefinition );
final AssociationKey associationKey = attributeDefinition.getAssociationKey();
// go ahead and build the bidirectional fetch
if ( attributeDefinition.getAssociationNature() == AssociationAttributeDefinition.AssociationNature.ENTITY ) {
final Joinable currentEntityPersister = (Joinable) currentSource().resolveEntityReference().getEntityPersister();
final AssociationKey currentEntityReferenceAssociationKey =
new AssociationKey( currentEntityPersister.getTableName(), currentEntityPersister.getKeyColumnNames() );
// if associationKey is equal to currentEntityReferenceAssociationKey
// that means that the current EntityPersister has a single primary key attribute
// (i.e., derived attribute) which is mapped by attributeDefinition.
// This is not a bidirectional association.
// TODO: AFAICT, to avoid an overflow, the associated entity must already be loaded into the session, or
// it must be loaded when the ID for the dependent entity is resolved. Is there some other way to
// deal with this???
final FetchSource registeredFetchSource = registeredFetchSource( associationKey );
if ( registeredFetchSource != null && ! associationKey.equals( currentEntityReferenceAssociationKey ) ) {
currentSource().buildBidirectionalEntityReference(
attributeDefinition,
fetchStrategy,
registeredFetchSource( associationKey ).resolveEntityReference()
);
}
}
else {
// Do nothing for collection
}
}
private String manyToManySelectFragment(
Joinable rhs,
String rhsAlias,
String lhsAlias,
String collectionSuffix) {
SelectFragment frag = generateSelectFragment( lhsAlias, collectionSuffix );
String[] elementColumnNames = rhs.getKeyColumnNames();
frag.addColumns( rhsAlias, elementColumnNames, elementColumnAliases );
appendIndexColumns( frag, lhsAlias );
appendIdentifierColumns( frag, lhsAlias );
return frag.toFragmentString()
.substring( 2 ); //strip leading ','
}
@Override
public String fromJoinFragment(
String alias,
boolean innerJoin,
boolean includeSubclasses,
Set<String> treatAsDeclarations) {
return ( (Joinable) getElementPersister() ).fromJoinFragment(
alias,
innerJoin,
includeSubclasses,
treatAsDeclarations
);
}
@Override
public String whereJoinFragment(
String alias,
boolean innerJoin,
boolean includeSubclasses,
Set<String> treatAsDeclarations) {
return ( (Joinable) getElementPersister() ).whereJoinFragment(
alias,
innerJoin,
includeSubclasses,
treatAsDeclarations
);
}
@Override
public String filterFragment(String alias) throws MappingException {
String result = super.filterFragment( alias );
if ( getElementPersister() instanceof Joinable ) {
result += ( (Joinable) getElementPersister() ).oneToManyFilterFragment( alias );
}
return result;
}
@Override
public AssociationKey getAssociationKey() {
final AssociationType type = getType();
if ( type.isAnyType() ) {
return new AssociationKey(
JoinHelper.getLHSTableName( type, attributeNumber(), (OuterJoinLoadable) getSource() ),
JoinHelper.getLHSColumnNames(
type,
attributeNumber(),
0,
(OuterJoinLoadable) getSource(),
sessionFactory()
)
);
}
final Joinable joinable = type.getAssociatedJoinable( sessionFactory() );
if ( type.getForeignKeyDirection() == ForeignKeyDirection.FROM_PARENT ) {
final String lhsTableName;
final String[] lhsColumnNames;
if ( joinable.isCollection() ) {
final QueryableCollection collectionPersister = (QueryableCollection) joinable;
lhsTableName = collectionPersister.getTableName();
lhsColumnNames = collectionPersister.getElementColumnNames();
}
else {
final OuterJoinLoadable entityPersister = (OuterJoinLoadable) source();
lhsTableName = getLHSTableName( type, attributeNumber(), entityPersister );
lhsColumnNames = getLHSColumnNames( type, attributeNumber(), entityPersister, sessionFactory() );
}
return new AssociationKey( lhsTableName, lhsColumnNames );
}
else {
return new AssociationKey( joinable.getTableName(), getRHSColumnNames( type, sessionFactory() ) );
}
}
protected Joinable getJoinable() {
if ( getAssociationNature() == AssociationNature.ANY ) {
throw new WalkingException( "Cannot resolve AnyType to a Joinable" );
}
if ( joinable == null ) {
joinable = getType().getAssociatedJoinable( sessionFactory() );
}
return joinable;
}
/**
* 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 void addSubclassJoins(
JoinFragment joinFragment,
String alias,
Joinable joinable,
boolean innerJoin,
boolean includeSubclassJoins,
Set<String> treatAsDeclarations) {
final boolean include = includeSubclassJoins && isIncluded( alias );
joinFragment.addJoins(
joinable.fromJoinFragment( alias, innerJoin, include, treatAsDeclarations ),
joinable.whereJoinFragment( alias, innerJoin, include, treatAsDeclarations )
);
}
private Map<String, String> mergeAliasMaps(SessionFactoryImplementor factory) {
Map<String, String> ret = new HashMap<String, String>();
if ( aliasTableMap != null ) {
ret.putAll( aliasTableMap );
}
if ( aliasEntityMap != null ) {
for ( Map.Entry<String, String> entry : aliasEntityMap.entrySet() ) {
ret.put(
entry.getKey(),
Joinable.class.cast( factory.getEntityPersister( entry.getValue() ) ).getTableName()
);
}
}
return ret;
}
private FromElement createAndAddFromElement(
String className,
String classAlias,
EntityPersister entityPersister,
EntityType type,
String tableAlias) {
if ( !( entityPersister instanceof Joinable ) ) {
throw new IllegalArgumentException( "EntityPersister " + entityPersister + " does not implement Joinable!" );
}
FromElement element = createFromElement( entityPersister );
initializeAndAddFromElement( element, className, classAlias, entityPersister, type, tableAlias );
return element;
}
private FromElement createFromElement(EntityPersister entityPersister) {
Joinable joinable = (Joinable) entityPersister;
String text = joinable.getTableName();
AST ast = createFromElement( text );
FromElement element = (FromElement) ast;
return element;
}
private boolean isManyToManyRoot(Joinable joinable) {
if ( joinable != null && joinable.isCollection() ) {
QueryableCollection persister = ( QueryableCollection ) joinable;
return persister.isManyToMany();
}
return false;
}
private FromElement createAndAddFromElement(
String className,
String classAlias,
EntityPersister entityPersister,
EntityType type,
String tableAlias) {
if ( !( entityPersister instanceof Joinable ) ) {
throw new IllegalArgumentException( "EntityPersister " + entityPersister + " does not implement Joinable!" );
}
FromElement element = createFromElement( entityPersister );
initializeAndAddFromElement( element, className, classAlias, entityPersister, type, tableAlias );
return element;
}
private boolean isManyToManyRoot(Joinable joinable) {
if ( joinable != null && joinable.isCollection() ) {
QueryableCollection persister = ( QueryableCollection ) joinable;
return persister.isManyToMany();
}
return false;
}
private boolean isManyToManyRoot(Joinable joinable) {
if ( joinable != null && joinable.isCollection() ) {
QueryableCollection persister = ( QueryableCollection ) joinable;
return persister.isManyToMany();
}
return false;
}
protected String generateTableAlias(
final int n,
final String path,
final Joinable joinable
) {
return StringHelper.generateAlias( joinable.getName(), n );
}
private boolean isManyToManyRoot(Joinable joinable) {
if ( joinable != null && joinable.isCollection() ) {
QueryableCollection persister = ( QueryableCollection ) joinable;
return persister.isManyToMany();
}
return false;
}
private boolean isManyToManyRoot(Joinable joinable) {
if ( joinable != null && joinable.isCollection() ) {
QueryableCollection persister = ( QueryableCollection ) joinable;
return persister.isManyToMany();
}
return false;
}
protected String generateTableAlias(int n, String path, Joinable joinable) {
if ( joinable.consumesEntityAlias() ) {
final Criteria subcriteria = translator.getCriteria(path);
String sqlAlias = subcriteria==null ? null : translator.getSQLAlias(subcriteria);
if (sqlAlias!=null) {
userAliasList.add( subcriteria.getAlias() ); //alias may be null
return sqlAlias; //EARLY EXIT
}
else {
userAliasList.add(null);
}
}
return super.generateTableAlias( n + translator.getSQLAliasCount(), path, joinable );
}