From 0a374404315c923e0714131d528f86ddb1538623 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 21 Jun 2012 10:19:20 -0500 Subject: [PATCH] HHH-7387 - Integrate Draft 6 of the JPA 2.1 spec : ON keyword --- hibernate-core/src/main/antlr/hql.g | 5 ++ .../hibernate/test/jpa/ql/OnKeywordTest.java | 48 +++++++++++++++ .../ejb/criteria/path/AbstractJoinImpl.java | 13 +++- .../hibernate/ejb/criteria/OnKeywordTest.java | 61 +++++++++++++++++++ 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/jpa/ql/OnKeywordTest.java create mode 100644 hibernate-entitymanager/src/test/java/org/hibernate/ejb/criteria/OnKeywordTest.java diff --git a/hibernate-core/src/main/antlr/hql.g b/hibernate-core/src/main/antlr/hql.g index 9289b0e070..ee63fa3ab0 100644 --- a/hibernate-core/src/main/antlr/hql.g +++ b/hibernate-core/src/main/antlr/hql.g @@ -336,6 +336,11 @@ fromJoin withClause : WITH^ logicalExpression + // JPA 2.1 support for an ON clause that isn't really an ON clause... + | ON! le:logicalExpression { + // it's really just a WITH clause, so treat it as such... + #withClause = #( [WITH, "with"], #le ); + } ; fromRange diff --git a/hibernate-core/src/test/java/org/hibernate/test/jpa/ql/OnKeywordTest.java b/hibernate-core/src/test/java/org/hibernate/test/jpa/ql/OnKeywordTest.java new file mode 100644 index 0000000000..b397dfd945 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/jpa/ql/OnKeywordTest.java @@ -0,0 +1,48 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, Red Hat Inc. or third-party contributors as + * indicated by the @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.test.jpa.ql; + +import java.math.BigDecimal; + +import org.hibernate.Session; + +import org.junit.Test; + +import org.hibernate.test.jpa.AbstractJPATest; + +/** + * Tests of the JPA decision (ugh) to use ON as a keyword for what Hibernate/HQL termed WITH. + * + * @author Steve Ebersole + */ +public class OnKeywordTest extends AbstractJPATest { + @Test + public void basicTest() { + Session s = openSession(); + s.createQuery( "select i from Item i join i.parts p on p.unitPrice > :filterPrice" ) + .setParameter( "filterPrice", new BigDecimal( 100 ) ) + .list(); + s.close(); + } +} diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/AbstractJoinImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/AbstractJoinImpl.java index 4e9415cd49..c07b23d135 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/AbstractJoinImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/ejb/criteria/path/AbstractJoinImpl.java @@ -36,6 +36,7 @@ import org.hibernate.ejb.criteria.CriteriaSubqueryImpl; import org.hibernate.ejb.criteria.FromImplementor; import org.hibernate.ejb.criteria.JoinImplementor; import org.hibernate.ejb.criteria.PathSource; +import org.hibernate.ejb.criteria.predicate.AbstractPredicateImpl; /** * Convenience base class for various {@link javax.persistence.criteria.Join} implementations. @@ -91,7 +92,17 @@ public abstract class AbstractJoinImpl public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext) { prepareAlias( renderingContext ); ( (FromImplementor) getParent() ).prepareAlias( renderingContext ); - return getParent().getAlias() + '.' + getAttribute().getName() + " as " + getAlias(); + StringBuilder tableExpression = new StringBuilder(); + tableExpression.append( getParent().getAlias() ) + .append( '.' ) + .append( getAttribute().getName() ) + .append( " as " ) + .append( getAlias() ); + if ( suppliedJoinCondition != null ) { + tableExpression.append( " with " ) + .append( ( (AbstractPredicateImpl) suppliedJoinCondition ).render( renderingContext ) ); + } + return tableExpression.toString(); } @Override diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/ejb/criteria/OnKeywordTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/criteria/OnKeywordTest.java new file mode 100644 index 0000000000..296f85dd88 --- /dev/null +++ b/hibernate-entitymanager/src/test/java/org/hibernate/ejb/criteria/OnKeywordTest.java @@ -0,0 +1,61 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2012, Red Hat Inc. or third-party contributors as + * indicated by the @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 javax.persistence.EntityManager; +import javax.persistence.criteria.CollectionJoin; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +import org.hibernate.ejb.metamodel.AbstractMetamodelSpecificTest; +import org.hibernate.ejb.metamodel.LineItem; +import org.hibernate.ejb.metamodel.LineItem_; +import org.hibernate.ejb.metamodel.Order; +import org.hibernate.ejb.metamodel.Order_; + +import org.junit.Test; + +/** + * Similar to {@link org.hibernate.test.jpa.ql.OnKeywordTest}, but here testing from JPA criteria queries. + * + * @author Steve Ebersole + */ +public class OnKeywordTest extends AbstractMetamodelSpecificTest { + @Test + public void basicTest() { + EntityManager em = getOrCreateEntityManager(); + CriteriaQuery criteria = em.getCriteriaBuilder().createQuery( Order.class ); + Root root = criteria.from( Order.class ); + criteria.select( root ); + CollectionJoin lineItemsJoin = root.join( Order_.lineItems ); + lineItemsJoin.on( + em.getCriteriaBuilder().gt( + lineItemsJoin.get( LineItem_.quantity ), + em.getCriteriaBuilder().literal( 20 ) + ) + ); + em.createQuery( criteria ).getResultList(); + em.close(); + } +}