1 package org.hibernate.criterion; 3 4 import org.hibernate.Criteria; 5 import org.hibernate.HibernateException; 6 import org.hibernate.MappingException; 7 import org.hibernate.QueryException; 8 import org.hibernate.engine.SessionFactoryImplementor; 9 import org.hibernate.engine.TypedValue; 10 import org.hibernate.persister.collection.QueryableCollection; 11 import org.hibernate.persister.entity.Loadable; 12 import org.hibernate.persister.entity.PropertyMapping; 13 import org.hibernate.sql.ConditionFragment; 14 import org.hibernate.type.CollectionType; 15 import org.hibernate.type.Type; 16 17 22 public abstract class AbstractEmptinessExpression implements Criterion { 23 24 private static final TypedValue[] NO_VALUES = new TypedValue[0]; 25 26 protected final String propertyName; 27 28 protected AbstractEmptinessExpression(String propertyName) { 29 this.propertyName = propertyName; 30 } 31 32 protected abstract boolean excludeEmpty(); 33 34 public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { 35 String entityName = criteriaQuery.getEntityName( criteria, propertyName ); 36 String actualPropertyName = criteriaQuery.getPropertyName( propertyName ); 37 String sqlAlias = criteriaQuery.getSQLAlias( criteria, propertyName ); 38 39 SessionFactoryImplementor factory = criteriaQuery.getFactory(); 40 QueryableCollection collectionPersister = getQueryableCollection( entityName, actualPropertyName, factory ); 41 42 String [] collectionKeys = collectionPersister.getKeyColumnNames(); 43 String [] ownerKeys = ( ( Loadable ) factory.getEntityPersister( entityName ) ).getIdentifierColumnNames(); 44 45 String innerSelect = "(select 1 from " + collectionPersister.getTableName() 46 + " where " 47 + new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString() 48 + ")"; 49 50 return excludeEmpty() 51 ? "exists " + innerSelect 52 : "not exists " + innerSelect; 53 } 54 55 56 protected QueryableCollection getQueryableCollection(String entityName, String propertyName, SessionFactoryImplementor factory) 57 throws HibernateException { 58 PropertyMapping ownerMapping = ( PropertyMapping ) factory.getEntityPersister( entityName ); 59 Type type = ownerMapping.toType( propertyName ); 60 if ( !type.isCollectionType() ) { 61 throw new MappingException( 62 "Property path [" + entityName + "." + propertyName + "] does not reference a collection" 63 ); 64 } 65 66 String role = ( ( CollectionType ) type ).getRole(); 67 try { 68 return ( QueryableCollection ) factory.getCollectionPersister( role ); 69 } 70 catch ( ClassCastException cce ) { 71 throw new QueryException( "collection role is not queryable: " + role ); 72 } 73 catch ( Exception e ) { 74 throw new QueryException( "collection role not found: " + role ); 75 } 76 } 77 78 public final TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 79 throws HibernateException { 80 return NO_VALUES; 81 } 82 83 public final String toString() { 84 return propertyName + ( excludeEmpty() ? " is not empty" : " is empty" ); 85 } 86 } 87 | Popular Tags |