[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