From 199ee7860ebec5adbcb419d454634f47e24ff8c0 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 3 Oct 2012 08:18:32 -0500 Subject: [PATCH] HHH-5209 - org.hibernate.hql.ast.QuerySyntaxException when running a JPQL query with a MEMBER OF on an @ElementCollection --- .../hibernate/hql/internal/ast/HqlParser.java | 14 +++-- .../EntityWithAnElementCollection.java | 57 +++++++++++++++++++ .../collectionelement/QueryTest.java | 51 +++++++++++++++++ 3 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/EntityWithAnElementCollection.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/QueryTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/HqlParser.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/HqlParser.java index 66403b0adf..b9f0bbd8e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/HqlParser.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/HqlParser.java @@ -383,11 +383,15 @@ public final class HqlParser extends HqlBaseParser { @Override public void processMemberOf(Token n, AST p, ASTPair currentAST) { - AST inAst = n == null ? astFactory.create( IN, "in" ) : astFactory.create( NOT_IN, "not in" ); - astFactory.makeASTRoot( currentAST, inAst ); - AST ast = createSubquery( p ); - ast = ASTUtil.createParent( astFactory, IN_LIST, "inList", ast ); - inAst.addChild( ast ); + // convert MEMBER OF to the equivalent IN ELEMENTS structure... + AST inNode = n == null ? astFactory.create( IN, "in" ) : astFactory.create( NOT_IN, "not in" ); + astFactory.makeASTRoot( currentAST, inNode ); + + AST inListNode = astFactory.create( IN_LIST, "inList" ); + inNode.addChild( inListNode ); + AST elementsNode = astFactory.create( ELEMENTS, "elements" ); + inListNode.addChild( elementsNode ); + elementsNode.addChild( p ); } static public void panic() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/EntityWithAnElementCollection.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/EntityWithAnElementCollection.java new file mode 100644 index 0000000000..f8a1996352 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/EntityWithAnElementCollection.java @@ -0,0 +1,57 @@ +/* + * 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.annotations.collectionelement; + +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Steve Ebersole + */ +@Entity +public class EntityWithAnElementCollection { + private Long id; + private Set someStrings = new HashSet(); + + @Id + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @ElementCollection + public Set getSomeStrings() { + return someStrings; + } + + public void setSomeStrings(Set someStrings) { + this.someStrings = someStrings; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/QueryTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/QueryTest.java new file mode 100644 index 0000000000..329711c086 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/QueryTest.java @@ -0,0 +1,51 @@ +/* + * 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.annotations.collectionelement; + +import org.hibernate.Session; + +import org.junit.Test; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + +/** + * @author Steve Ebersole + */ +public class QueryTest extends BaseCoreFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { EntityWithAnElementCollection.class }; + } + + @Test + @TestForIssue( jiraKey = "HHH-5209" ) + public void testMemberOfSyntax() { + // performs syntax checking of the MEMBER OF predicate against a basic collection + Session s = openSession(); +// s.createQuery( "from EntityWithAnElementCollection e where 'abc' in elements( e.someStrings )" ).list(); + s.createQuery( "from EntityWithAnElementCollection e where 'abc' member of e.someStrings" ).list(); + s.close(); + } +}