1 package org.hibernate.loader; 3 4 import java.util.List ; 5 import java.util.Map ; 6 7 import org.hibernate.MappingException; 8 import org.hibernate.engine.JoinHelper; 9 import org.hibernate.engine.SessionFactoryImplementor; 10 import org.hibernate.persister.collection.QueryableCollection; 11 import org.hibernate.persister.entity.Joinable; 12 import org.hibernate.sql.JoinFragment; 13 import org.hibernate.type.AssociationType; 14 import org.hibernate.type.EntityType; 15 16 public final class OuterJoinableAssociation { 17 private final AssociationType joinableType; 18 private final Joinable joinable; 19 private final String lhsAlias; private final String [] lhsColumns; private final String rhsAlias; 22 private final String [] rhsColumns; 23 private final int joinType; 24 private final String on; 25 private final Map enabledFilters; 26 27 public OuterJoinableAssociation( 28 AssociationType joinableType, 29 String lhsAlias, 30 String [] lhsColumns, 31 String rhsAlias, 32 int joinType, 33 SessionFactoryImplementor factory, 34 Map enabledFilters) 35 throws MappingException { 36 this.joinableType = joinableType; 37 this.lhsAlias = lhsAlias; 38 this.lhsColumns = lhsColumns; 39 this.rhsAlias = rhsAlias; 40 this.joinType = joinType; 41 this.joinable = joinableType.getAssociatedJoinable(factory); 42 this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory); 43 this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters); 44 this.enabledFilters = enabledFilters; } 46 47 public int getJoinType() { 48 return joinType; 49 } 50 51 public String getRHSAlias() { 52 return rhsAlias; 53 } 54 55 private boolean isOneToOne() { 56 if ( joinableType.isEntityType() ) { 57 EntityType etype = (EntityType) joinableType; 58 return etype.isOneToOne() ; 59 } 60 else { 61 return false; 62 } 63 64 } 65 66 public AssociationType getJoinableType() { 67 return joinableType; 68 } 69 70 public String getRHSUniqueKeyName() { 71 return joinableType.getRHSUniqueKeyPropertyName(); 72 } 73 74 public boolean isCollection() { 75 return joinableType.isCollectionType(); 76 } 77 78 public Joinable getJoinable() { 79 return joinable; 80 } 81 82 public int getOwner(final List associations) { 83 if ( isOneToOne() || isCollection() ) { 84 return getPosition(lhsAlias, associations); 85 } 86 else { 87 return -1; 88 } 89 } 90 91 95 private static int getPosition(String lhsAlias, List associations) { 96 int result = 0; 97 for ( int i=0; i<associations.size(); i++ ) { 98 OuterJoinableAssociation oj = (OuterJoinableAssociation) associations.get(i); 99 if ( oj.getJoinable().consumesEntityAlias() ) { 100 if ( oj.rhsAlias.equals(lhsAlias) ) return result; 101 result++; 102 } 103 } 104 return -1; 105 } 106 107 public void addJoins(JoinFragment outerjoin) throws MappingException { 108 outerjoin.addJoin( 109 joinable.getTableName(), 110 rhsAlias, 111 lhsColumns, 112 rhsColumns, 113 joinType, 114 on 115 ); 116 outerjoin.addJoins( 117 joinable.fromJoinFragment(rhsAlias, false, true), 118 joinable.whereJoinFragment(rhsAlias, false, true) 119 ); 120 } 121 122 public void validateJoin(String path) throws MappingException { 123 if ( 124 rhsColumns==null || 125 lhsColumns==null || 126 lhsColumns.length!=rhsColumns.length || 127 lhsColumns.length==0 128 ) { 129 throw new MappingException("invalid join columns for association: " + path); 130 } 131 } 132 133 public boolean isManyToManyWith(OuterJoinableAssociation other) { 134 if ( joinable.isCollection() ) { 135 QueryableCollection persister = ( QueryableCollection ) joinable; 136 if ( persister.isManyToMany() ) { 137 return persister.getElementType() == other.getJoinableType(); 138 } 139 } 140 return false; 141 } 142 143 public void addManyToManyJoin(JoinFragment outerjoin, QueryableCollection collection) throws MappingException { 144 String manyToManyFilter = collection.getManyToManyFilterFragment( rhsAlias, enabledFilters ); 145 String condition = "".equals( manyToManyFilter ) 146 ? on 147 : "".equals( on ) 148 ? manyToManyFilter 149 : on + " and " + manyToManyFilter; 150 outerjoin.addJoin( 151 joinable.getTableName(), 152 rhsAlias, 153 lhsColumns, 154 rhsColumns, 155 joinType, 156 condition 157 ); 158 outerjoin.addJoins( 159 joinable.fromJoinFragment(rhsAlias, false, true), 160 joinable.whereJoinFragment(rhsAlias, false, true) 161 ); 162 } 163 } | Popular Tags |