diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java index faa1f100c0..28188cbaba 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IdentNode.java @@ -31,6 +31,7 @@ import antlr.collections.AST; import org.hibernate.QueryException; import org.hibernate.dialect.function.SQLFunction; +import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes; import org.hibernate.hql.internal.antlr.SqlTokenTypes; import org.hibernate.hql.internal.ast.util.ColumnHelper; import org.hibernate.internal.util.StringHelper; @@ -155,18 +156,27 @@ public class IdentNode extends FromReferenceNode implements SelectExpression { setFromElement( element ); String[] columnExpressions = element.getIdentityColumns(); final boolean isInNonDistinctCount = getWalker().isInCount() && ! getWalker().isInCountDistinct(); - final boolean isCompositePk = columnExpressions.length > 1; - if ( isCompositePk - && isInNonDistinctCount - && ! getWalker().getSessionFactoryHelper().getFactory().getDialect().supportsTupleCounts() ) { - setText( columnExpressions[0] ); + final boolean isCompositeValue = columnExpressions.length > 1; + if ( isCompositeValue ) { + if ( isInNonDistinctCount && ! getWalker().getSessionFactoryHelper().getFactory().getDialect().supportsTupleCounts() ) { + setText( columnExpressions[0] ); + } + else { + String joinedFragment = StringHelper.join( ", ", columnExpressions ); + // avoid wrapping in parenthesis (explicit tuple treatment) if possible due to varied support for + // tuple syntax across databases.. + final boolean shouldSkipWrappingInParenthesis = + getWalker().isInCount() + || getWalker().getCurrentTopLevelClauseType() == HqlSqlTokenTypes.ORDER + || getWalker().getCurrentTopLevelClauseType() == HqlSqlTokenTypes.GROUP; + if ( ! shouldSkipWrappingInParenthesis ) { + joinedFragment = "(" + joinedFragment + ")"; + } + setText( joinedFragment ); + } } else { - String joinedFragment = StringHelper.join( ", ", columnExpressions ); - if ( ! getWalker().isInCount() ) { - joinedFragment = "(" + joinedFragment + ")"; - } - setText( joinedFragment ); + setText( columnExpressions[0] ); } return true; } diff --git a/hibernate-entitymanager/src/matrix/java/org/hibernate/ejb/test/query/ComponentJoinsTest.java b/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/ComponentJoinsTest.java similarity index 59% rename from hibernate-entitymanager/src/matrix/java/org/hibernate/ejb/test/query/ComponentJoinsTest.java rename to hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/ComponentJoinsTest.java index 4447c2d2e7..788f19003d 100644 --- a/hibernate-entitymanager/src/matrix/java/org/hibernate/ejb/test/query/ComponentJoinsTest.java +++ b/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/ComponentJoinsTest.java @@ -21,41 +21,40 @@ * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA\ */ -package org.hibernate.ejb.test.query; +package org.hibernate.test.component.basic2; -import javax.persistence.EntityManager; - -import org.hibernate.ejb.criteria.components.Client; -import org.hibernate.ejb.test.BaseEntityManagerFunctionalTestCase; +import org.hibernate.Session; import org.junit.Test; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + /** * Tests related to specifying joins on components (embedded values). * * @author Steve Ebersole */ -public class ComponentJoinsTest extends BaseEntityManagerFunctionalTestCase { +public class ComponentJoinsTest extends BaseCoreFunctionalTestCase { @Override public Class[] getAnnotatedClasses() { - return new Class[] { Client.class }; + return new Class[] { Person.class }; } @Test public void testComponentJoins() { // Just checking proper query construction and syntax checking via database query parser... - EntityManager em = getOrCreateEntityManager(); - em.getTransaction().begin(); + Session session = openSession(); + session.beginTransaction(); // use it in WHERE - em.createQuery( "select c from Client c join c.name as n where n.lastName like '%'" ).getResultList(); + session.createQuery( "select p from Person p join p.name as n where n.lastName like '%'" ).list(); // use it in SELECT - em.createQuery( "select n.lastName from Client c join c.name as n" ).getResultList(); - em.createQuery( "select n from Client c join c.name as n" ).getResultList(); + session.createQuery( "select n.lastName from Person p join p.name as n" ).list(); + session.createQuery( "select n from Person p join p.name as n" ).list(); // use it in ORDER BY - em.createQuery( "select n from Client c join c.name as n order by n.lastName" ).getResultList(); - em.createQuery( "select n from Client c join c.name as n order by c" ).getResultList(); - em.createQuery( "select n from Client c join c.name as n order by n" ).getResultList(); - em.getTransaction().commit(); - em.close(); + session.createQuery( "select n from Person p join p.name as n order by n.lastName" ).list(); + session.createQuery( "select n from Person p join p.name as n order by p" ).list(); + session.createQuery( "select n from Person p join p.name as n order by n" ).list(); + session.getTransaction().commit(); + session.close(); } } diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/Name.java b/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/Name.java new file mode 100644 index 0000000000..1e78afd574 --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/Name.java @@ -0,0 +1,63 @@ +/* + * 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.component.basic2; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +/** + * @author Steve Ebersole + */ +@Embeddable +public class Name implements Serializable { + private String firstName; + private String lastName; + + public Name() { + } + + public Name(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + @Column(name = "FIRST_NAME", nullable = false) + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + @Column(name = "LAST_NAME", nullable = false) + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} \ No newline at end of file diff --git a/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/Person.java b/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/Person.java new file mode 100644 index 0000000000..d75eac6e53 --- /dev/null +++ b/hibernate-core/src/matrix/java/org/hibernate/test/component/basic2/Person.java @@ -0,0 +1,68 @@ +/* + * 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.component.basic2; + +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import java.io.Serializable; + +/** + * @author Steve Ebersole + */ +@Entity +public class Person implements Serializable { + private int id; + private Name name; + + public Person() { + } + + public Person(int id, Name name) { + this.id = id; + this.name = name; + } + + public Person(int id, String firstName, String lastName) { + this( id, new Name( firstName, lastName ) ); + } + + @Id + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @Embedded + public Name getName() { + return name; + } + + public void setName(Name name) { + this.name = name; + } +}