Author: gbadner
Date: 2007-11-28 20:36:04 -0500 (Wed, 28 Nov 2007)
New Revision: 14209
Modified:
core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java
core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java
core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java
core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
HHH-952 : subqueries with joins using DetatchedCriteria
Modified: core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java
===================================================================
---
core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java 2007-11-28
22:10:08 UTC (rev 14208)
+++
core/branches/Branch_3_2/src/org/hibernate/criterion/SubqueryExpression.java 2007-11-29
01:36:04 UTC (rev 14209)
@@ -1,17 +1,18 @@
//$Id$
package org.hibernate.criterion;
+import java.util.HashMap;
+
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.TypedValue;
import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.loader.criteria.CriteriaJoinWalker;
import org.hibernate.loader.criteria.CriteriaQueryTranslator;
import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.sql.Select;
import org.hibernate.type.Type;
/**
@@ -24,7 +25,8 @@
private String op;
private QueryParameters params;
private Type[] types;
-
+ private CriteriaQueryTranslator innerQuery;
+
protected Type[] getTypes() {
return types;
}
@@ -39,34 +41,23 @@
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
-
- final SessionImplementor session = ( (CriteriaImpl) criteria ).getSession(); //ugly!
- final SessionFactoryImplementor factory = session.getFactory();
-
+
+ final SessionFactoryImplementor factory = criteriaQuery.getFactory();
final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister(
criteriaImpl.getEntityOrClassName() );
- CriteriaQueryTranslator innerQuery = new CriteriaQueryTranslator(
- factory,
- criteriaImpl,
- criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would
need a union)
- criteriaQuery.generateSQLAlias(),
- criteriaQuery
- );
+
+ createAndSetInnerQuery( criteriaQuery, factory );
- params = innerQuery.getQueryParameters(); //TODO: bad lifecycle....
- types = innerQuery.getProjectedTypes();
-
- //String filter = persister.filterFragment( innerQuery.getRootSQLALias(),
session.getEnabledFilters() );
-
- String sql = new Select( factory.getDialect() )
- .setWhereClause( innerQuery.getWhereCondition() )
- .setGroupByClause( innerQuery.getGroupBy() )
- .setSelectClause( innerQuery.getSelect() )
- .setFromClause(
- persister.fromTableFragment( innerQuery.getRootSQLALias() ) +
- persister.fromJoinFragment( innerQuery.getRootSQLALias(), true, false )
- )
- .toStatementString();
-
+ CriteriaJoinWalker walker = new CriteriaJoinWalker(
+ persister,
+ innerQuery,
+ factory,
+ criteriaImpl,
+ criteriaImpl.getEntityOrClassName(),
+ new HashMap(),
+ innerQuery.getRootSQLALias());
+
+ String sql = walker.getSQLString();
+
final StringBuffer buf = new StringBuffer()
.append( toLeftSqlString(criteria, criteriaQuery) );
if (op!=null) buf.append(' ').append(op).append(' ');
@@ -77,13 +68,49 @@
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
- Type[] types = params.getPositionalParameterTypes();
- Object[] values = params.getPositionalParameterValues();
- TypedValue[] tv = new TypedValue[types.length];
- for ( int i=0; i<types.length; i++ ) {
- tv[i] = new TypedValue( types[i], values[i], EntityMode.POJO );
+ //the following two lines were added to ensure that this.params is not null, which
+ //can happen with two-deep nested subqueries
+ SessionFactoryImplementor factory = criteriaQuery.getFactory();
+ createAndSetInnerQuery(criteriaQuery, factory);
+
+ Type[] ppTypes = params.getPositionalParameterTypes();
+ Object[] ppValues = params.getPositionalParameterValues();
+ TypedValue[] tv = new TypedValue[ppTypes.length];
+ for ( int i=0; i<ppTypes.length; i++ ) {
+ tv[i] = new TypedValue( ppTypes[i], ppValues[i], EntityMode.POJO );
}
return tv;
}
+ /**
+ * Creates the inner query used to extract some useful information about
+ * types, since it is needed in both methods.
+ * @param criteriaQuery
+ * @param factory
+ */
+ private void createAndSetInnerQuery(CriteriaQuery criteriaQuery, final
SessionFactoryImplementor factory) {
+ if ( innerQuery == null ) {
+ //with two-deep subqueries, the same alias would get generated for
+ //both using the old method (criteriaQuery.generateSQLAlias()), so
+ //that is now used as a fallback if the main criteria alias isn't set
+ String alias;
+ if ( this.criteriaImpl.getAlias() == null ) {
+ alias = criteriaQuery.generateSQLAlias();
+ }
+ else {
+ alias = this.criteriaImpl.getAlias() + "_";
+ }
+
+ innerQuery = new CriteriaQueryTranslator(
+ factory,
+ criteriaImpl,
+ criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would
need a union)
+ alias,
+ criteriaQuery
+ );
+
+ params = innerQuery.getQueryParameters();
+ types = innerQuery.getProjectedTypes();
+ }
+ }
}
Modified: core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
---
core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java 2007-11-28
22:10:08 UTC (rev 14208)
+++
core/branches/Branch_3_2/src/org/hibernate/loader/AbstractEntityJoinWalker.java 2007-11-29
01:36:04 UTC (rev 14209)
@@ -26,12 +26,16 @@
public abstract class AbstractEntityJoinWalker extends JoinWalker {
private final OuterJoinLoadable persister;
- private String alias;
+ private final String alias;
public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor
factory, Map enabledFilters) {
+ this( persister, factory, enabledFilters, null );
+ }
+
+ public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor
factory, Map enabledFilters, String alias) {
super( factory, enabledFilters );
this.persister = persister;
- alias = generateRootAlias( persister.getEntityName() );
+ this.alias = ( alias == null ) ? generateRootAlias( persister.getEntityName() ) :
alias;
}
protected final void initAll(
@@ -39,9 +43,7 @@
final String orderByString,
final LockMode lockMode)
throws MappingException {
-
walkEntityTree( persister, getAlias() );
-
List allAssociations = new ArrayList();
allAssociations.addAll(associations);
allAssociations.add( new OuterJoinableAssociation(
Modified:
core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java
===================================================================
---
core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java 2007-11-28
22:10:08 UTC (rev 14208)
+++
core/branches/Branch_3_2/src/org/hibernate/loader/criteria/CriteriaJoinWalker.java 2007-11-29
01:36:04 UTC (rev 14209)
@@ -8,7 +8,6 @@
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.engine.CascadeStyle;
@@ -18,7 +17,6 @@
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.OuterJoinLoadable;
import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
import org.hibernate.type.AssociationType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
@@ -57,10 +55,20 @@
final SessionFactoryImplementor factory,
final CriteriaImpl criteria,
final String rootEntityName,
- final Map enabledFilters)
- throws HibernateException {
- super(persister, factory, enabledFilters);
+ final Map enabledFilters) {
+ this(persister, translator, factory, criteria, rootEntityName, enabledFilters, null);
+ }
+ public CriteriaJoinWalker(
+ final OuterJoinLoadable persister,
+ final CriteriaQueryTranslator translator,
+ final SessionFactoryImplementor factory,
+ final CriteriaImpl criteria,
+ final String rootEntityName,
+ final Map enabledFilters,
+ final String alias) {
+ super(persister, factory, enabledFilters, alias);
+
this.translator = translator;
querySpaces = translator.getQuerySpaces();
Modified:
core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
---
core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2007-11-28
22:10:08 UTC (rev 14208)
+++
core/branches/Branch_3_2/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2007-11-29
01:36:04 UTC (rev 14209)
@@ -16,7 +16,6 @@
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
-import org.hibernate.criterion.Expression;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
@@ -154,8 +153,8 @@
.list();
session.createCriteria(Student.class)
- .add( Property.forName("name").eqAll(dc) )
- .list();
+ .add( Property.forName("name").eqAll(dc) )
+ .list();
session.createCriteria(Student.class)
.add( Subqueries.in("Gavin King", dc) )
@@ -169,8 +168,7 @@
.add( Subqueries.eq("Gavin King", dc2) )
.list();
- //TODO: join in subselect: HHH-952
- /*DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st")
+ DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st")
.createCriteria("enrolments")
.createCriteria("course")
.add( Property.forName("description").eq("Hibernate Training")
)
@@ -178,7 +176,7 @@
session.createCriteria(Enrolment.class, "e")
.add( Subqueries.eq("Gavin King", dc3) )
- .list();*/
+ .list();
session.delete(enrolment2);
session.delete(gavin);
@@ -398,8 +396,8 @@
.add( Projections.property("studentNumber"), "stNumber" )
.add( Projections.property("courseCode"), "cCode" ) )
)
- .add( Expression.gt( "studentNumber", new Long(665) ) )
- .add( Expression.lt( "studentNumber", new Long(668) ) )
+ .add( Restrictions.gt( "studentNumber", new Long(665) ) )
+ .add( Restrictions.lt( "studentNumber", new Long(668) ) )
.addOrder( Order.asc("stNumber") )
.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
.list();