[hibernate-commits] Hibernate SVN: r17772 - in core/trunk/entitymanager/src/main/java/org/hibernate/ejb: criteria and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Oct 15 20:50:22 EDT 2009


Author: steve.ebersole at jboss.com
Date: 2009-10-15 20:50:22 -0400 (Thu, 15 Oct 2009)
New Revision: 17772

Added:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java
Modified:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryImpl.java
Log:
HHH-4203 - Implement JPA 2.0 criteria apis (compiling)


Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java	2009-10-15 23:44:41 UTC (rev 17771)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java	2009-10-16 00:50:22 UTC (rev 17772)
@@ -42,7 +42,7 @@
 import javax.persistence.TransactionRequiredException;
 import javax.persistence.TypedQuery;
 import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.QueryBuilder;
+import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.metamodel.Metamodel;
 import javax.persistence.spi.PersistenceUnitTransactionType;
 import javax.transaction.Status;
@@ -72,6 +72,7 @@
 import org.hibernate.cfg.Environment;
 import org.hibernate.ejb.transaction.JoinableCMTTransaction;
 import org.hibernate.ejb.util.ConfigurationHelper;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.engine.SessionImplementor;
 import org.hibernate.proxy.HibernateProxy;
@@ -148,40 +149,15 @@
 		}
 	}
 
+	private CriteriaQueryCompiler criteriaQueryCompiler;
+
 	public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
-		// TODO-STEVE : here is the interpretation/compilation portion.
-		// 		One option is to build on top of the existing
-		//		org.hibernate.loader.custom.CustomQuery infastructure
-		// 		(which is how native sql queries are implemented e.g.).
-		//		If so, then here we could interpret the criteria into
-		//		a CustomQuery instance which is passed into the
-		//		Query instance returned here.  We would then call into
-		//		the various SessionImplementor methods for execution
-		//		such as #listCustomQuery and #scrollCustomQuery.
-		//
-		// 		The drawback to this (^^) approach is that CustomQuery +
-		//		SessionImplementor combo does not support #executeUpdate
-		//		processing...
-		throw new UnsupportedOperationException( "Not yet implemented!" );
+		if ( criteriaQueryCompiler == null ) {
+			criteriaQueryCompiler = new CriteriaQueryCompiler( this );
+		}
+		return criteriaQueryCompiler.compile( criteriaQuery );
 	}
 
-	public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery, Class<T> resultClass) {
-		// TODO-STEVE : here is the interpretation/compilation portion.
-		// 		One option is to build on top of the existing
-		//		org.hibernate.loader.custom.CustomQuery infastructure
-		// 		(which is how native sql queries are implemented e.g.).
-		//		If so, then here we could interpret the criteria into
-		//		a CustomQuery instance which is passed into the
-		//		Query instance returned here.  We would then call into
-		//		the various SessionImplementor methods for execution
-		//		such as #listCustomQuery and #scrollCustomQuery.
-		//
-		// 		The drawback to this (^^) approach is that CustomQuery +
-		//		SessionImplementor combo does not support #executeUpdate
-		//		processing...
-		throw new UnsupportedOperationException( "Not yet implemented!" );
-	}
-
 	public Query createNamedQuery(String name) {
 		try {
 			org.hibernate.Query namedQuery = getSession().getNamedQuery( name );
@@ -481,8 +457,8 @@
 	/**
 	 * {@inheritDoc}
 	 */
-	public QueryBuilder getQueryBuilder() {
-		return getEntityManagerFactory().getQueryBuilder();
+	public CriteriaBuilder getCriteriaBuilder() {
+		return getEntityManagerFactory().getCriteriaBuilder();
 	}
 
 	/**
@@ -672,13 +648,13 @@
 									}
 									catch ( SystemException se ) {
 										log.error( "could not determine transaction status", se );
-										//throwPersistenceException will mark the transaction as rollbacked
-										throwPersistenceException(
-												new PersistenceException(
-														"could not determine transaction status in beforeCompletion()",
-														se
-												)
+										PersistenceException pe = new PersistenceException(
+												"could not determine transaction status in beforeCompletion()",
+												se
 										);
+										// handlePersistenceException will mark the transaction as rollbacked
+										handlePersistenceException( pe );
+										throw pe;
 									}
 									catch ( HibernateException he ) {
 										throwPersistenceException( he );

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java	2009-10-15 23:44:41 UTC (rev 17771)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java	2009-10-16 00:50:22 UTC (rev 17772)
@@ -21,8 +21,6 @@
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
  */
-
-//$Id$
 package org.hibernate.ejb;
 
 import java.util.Calendar;
@@ -150,7 +148,7 @@
 			return position;
 		}
 
-		public Class getJavaType() {
+		public Class getParameterType() {
 			return javaType;
 		}
 	}
@@ -521,10 +519,10 @@
 	@SuppressWarnings({ "unchecked" })
 	public <T> Parameter<T> getParameter(String name, Class<T> type) {
 		Parameter param = getParameter( name );
-		if ( param.getJavaType() != null ) {
+		if ( param.getParameterType() != null ) {
 			// we were able to determine the expected type during analysis, so validate it here
 			throw new IllegalArgumentException(
-					"Parameter type [" + param.getJavaType().getName() +
+					"Parameter type [" + param.getParameterType().getName() +
 							"] is not assignment compatible with requested type [" +
 							type.getName() + "]"
 			);
@@ -538,10 +536,10 @@
 	@SuppressWarnings({ "unchecked" })
 	public <T> Parameter<T> getParameter(int position, Class<T> type) {
 		Parameter param = getParameter( position );
-		if ( param.getJavaType() != null ) {
+		if ( param.getParameterType() != null ) {
 			// we were able to determine the expected type during analysis, so validate it here
 			throw new IllegalArgumentException(
-					"Parameter type [" + param.getJavaType().getName() +
+					"Parameter type [" + param.getParameterType().getName() +
 							"] is not assignment compatible with requested type [" +
 							type.getName() + "]"
 			);

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryCompiler.java	2009-10-16 00:50:22 UTC (rev 17772)
@@ -0,0 +1,61 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors.  All
+ * third-party contributions are distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.ejb.criteria;
+
+import java.util.Set;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.ParameterExpression;
+
+import org.hibernate.ejb.HibernateEntityManagerImplementor;
+
+/**
+ * Compiles a JPA criteria query into an executable {@link TypedQuery}.  Its single contract is the {@link #compile}
+ * method.
+ * <p/>
+ * NOTE : This is a temporay implementation which simply translates the criteria query into a JPAQL query string.  A
+ * better, long-term solution is being implemented as part of refactoring the JPAQL/HQL translator.
+ *
+ * @author Steve Ebersole
+ */
+public class CriteriaQueryCompiler {
+	private final HibernateEntityManagerImplementor entityManager;
+
+	public CriteriaQueryCompiler(HibernateEntityManagerImplementor entityManager) {
+		this.entityManager = entityManager;
+	}
+
+	public <T> TypedQuery<T> compile(CriteriaQuery<T> criteriaQuery) {
+		CriteriaQueryImpl<T> criteriaQueryImpl = ( CriteriaQueryImpl<T> ) criteriaQuery;
+
+		criteriaQueryImpl.validate();
+		Set<ParameterExpression<?>> explicitParameters = criteriaQueryImpl.getParameters();
+		// todo : implicit parameter handling (handling literal as param, etc).
+		String jpaqlEquivalent = criteriaQueryImpl.render();
+
+
+
+		return null;
+	}
+}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryImpl.java	2009-10-15 23:44:41 UTC (rev 17771)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/CriteriaQueryImpl.java	2009-10-16 00:50:22 UTC (rev 17772)
@@ -293,4 +293,44 @@
 		return queryStructure.subquery( subqueryType );
 	}
 
+	public void validate() {
+		// getRoots() is explicitly supposed to return empty if none defined, no need to check for null
+		if ( getRoots().isEmpty() ) {
+			throw new IllegalStateException( "No criteria query roots were specified" );
+		}
+
+		// if there is not an explicit selection, there is an *implicit* selection of the root entity provided only
+		// a single query root was defined.
+		if ( getSelection() == null && !hasImplicitSelection() ) {
+			throw new IllegalStateException( "No explicit selection and an implicit one cold not be determined" );
+		}
+	}
+
+	/**
+	 * If no explicit selection was defined, we have a condition called an implicit selection if the query specified
+	 * a single {@link Root} and the java type of that {@link Root root's} model is the same as this criteria's
+	 * {@link #getResultType() result type}.
+	 *
+	 * @return True if there is an explicit selection; false otherwise.
+	 */
+	private boolean hasImplicitSelection() {
+		if ( getRoots().size() != 1 ) {
+			return false;
+		}
+
+		Root root = getRoots().iterator().next();
+		if ( root.getModel().getJavaType() != returnType ) {
+			return false;
+		}
+
+		// if we get here, the query defined no selection but defined a single root of the same type as the
+		// criteria query return, so we use that as the implicit selection
+		//
+		// todo : should we put an implicit marker in the selection to this fact to make later processing easier?
+		return true;
+	}
+
+	public String render() {
+		return null;
+	}
 }



More information about the hibernate-commits mailing list