From 63881f137ed7a7c5d4e48f2a20e077d0d47ad6f3 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Fri, 14 Mar 2014 15:57:05 -0700 Subject: [PATCH] HHH-9002 : Fetch many-to-many order by --- .../LoadQueryJoinAndFetchProcessor.java | 2 +- .../test/annotations/onetomany/A.java | 89 +++++++++++++++++++ .../test/annotations/onetomany/B.java | 83 +++++++++++++++++ .../test/annotations/onetomany/C.java | 65 ++++++++++++++ .../annotations/onetomany/OrderByTest.java | 70 ++++++++++++++- 5 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/A.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/B.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/C.java diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/LoadQueryJoinAndFetchProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/LoadQueryJoinAndFetchProcessor.java index 3b2d05c3b6..8153255da0 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/LoadQueryJoinAndFetchProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/LoadQueryJoinAndFetchProcessor.java @@ -571,7 +571,7 @@ public class LoadQueryJoinAndFetchProcessor { ); // add SQL ORDER-BY fragments - final String manyToManyOrdering = queryableCollection.getManyToManyOrderByString( collectionTableAlias ); + final String manyToManyOrdering = queryableCollection.getManyToManyOrderByString( elementTableAlias ); if ( StringHelper.isNotEmpty( manyToManyOrdering ) ) { selectStatementBuilder.appendOrderByFragment( manyToManyOrdering ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/A.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/A.java new file mode 100644 index 0000000000..7b4886baf4 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/A.java @@ -0,0 +1,89 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, 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.onetomany; + +import java.awt.List; +import java.util.ArrayList; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import javax.validation.constraints.NotNull; + +import org.hibernate.annotations.Cascade; + +/** + * @author Peter Kotula + */ +@Entity +public class A { + @GeneratedValue(strategy = GenerationType.AUTO) + @Id + Long id; + + + @NotNull + String name; + + @OneToMany( cascade = CascadeType.ALL) + @Cascade(org.hibernate.annotations.CascadeType.ALL) + @OrderBy("name") + java.util.List bs = new ArrayList(); + + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public java.util.List getBs() { + return bs; + } + +// public void setBs(java.util.List bs) { +// this.bs = bs; +// } + + @Override + public String toString() { + return "A [id=" + id + ", name=" + name + ", bs=" + bs + "]"; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/B.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/B.java new file mode 100644 index 0000000000..81c9f148b9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/B.java @@ -0,0 +1,83 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, 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.onetomany; + +import java.util.ArrayList; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import javax.validation.constraints.NotNull; + +import org.hibernate.annotations.Cascade; + +/** + * @author Peter Kotula + */ +@Entity +public class B { + @GeneratedValue(strategy = GenerationType.AUTO) + @Id + Long id; + + @NotNull + String name; + + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @Cascade(org.hibernate.annotations.CascadeType.ALL) + @OrderBy("name") + java.util.List cs = new ArrayList(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public java.util.List getCs() { + return cs; + } + + @Override + public String toString() { + return "B [id=" + id + ", name=" + name + ", cs="+cs+"]"; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/C.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/C.java new file mode 100644 index 0000000000..098bc1e193 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/C.java @@ -0,0 +1,65 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, 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.onetomany; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.validation.constraints.NotNull; + +/** + * @author Peter Kotula + */ +@Entity +public class C { + @GeneratedValue(strategy = GenerationType.AUTO) + @Id + Long id; + + @NotNull + String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "C [id=" + id + ", name=" + name + "]"; + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java index c1f631a1c3..f3649bbc22 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java @@ -442,6 +442,73 @@ public class OrderByTest extends BaseCoreFunctionalTestCase { assertEquals( 2, employee.getAssets().get( 1 ).getIdAsset().intValue() ); } + @Test + @TestForIssue( jiraKey = "HHH-9002" ) + public void testOrderByOneToManyWithJoinTable() { + A a = new A(); + a.setName( "a" ); + B b1 = new B(); + b1.setName( "b1" ); + B b2 = new B(); + b2.setName( "b2" ); + C c11 = new C(); + c11.setName( "c11" ); + C c12 = new C(); + c12.setName( "c12" ); + C c21 = new C(); + c21.setName( "c21" ); + C c22 = new C(); + c22.setName( "c22" ); + + a.getBs().add( b1 ); + a.getBs().add( b2 ); + b1.getCs().add( c11 ); + b1.getCs().add( c12 ); + b2.getCs().add( c21 ); + b2.getCs().add( c22 ); + + Session s = openSession(); + s.getTransaction().begin(); + s.persist( a ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.getTransaction().begin(); + + b1 = (B) s.get( B.class, b1.getId() ); + assertEquals( "b1", b1.getName() ); + List cs = b1.getCs(); + assertEquals( 2, cs.size() ); + assertEquals( "c11", cs.get( 0 ).getName() ); + assertEquals( "c12", cs.get( 1 ).getName() ); + + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.getTransaction().begin(); + + a = (A) s.get( A.class, a.getId() ); + assertEquals( "a", a.getName() ); + assertEquals( 2, a.getBs().size() ); + List bs = a.getBs(); + assertEquals( "b1", bs.get( 0 ).getName() ); + assertEquals( "b2", bs.get( 1 ).getName() ); + List b1cs = bs.get( 0 ).getCs(); + assertEquals( 2, b1cs.size() ); + assertEquals( "c11", b1cs.get( 0 ).getName() ); + assertEquals( "c12", b1cs.get( 1 ).getName() ); + List b2cs = bs.get( 1 ).getCs(); + assertEquals( 2, b2cs.size() ); + assertEquals( "c21", b2cs.get( 0 ).getName() ); + assertEquals( "c22", b2cs.get( 1 ).getName() ); + + s.delete( a ); + + s.getTransaction().commit(); + s.close(); + } @Override protected Class[] getAnnotatedClasses() { @@ -450,7 +517,8 @@ public class OrderByTest extends BaseCoreFunctionalTestCase { Monkey.class, Visitor.class, Box.class, Item.class, BankAccount.class, Transaction.class, Comment.class, Forum.class, Post.class, User.class, - Asset.class, Computer.class, Employee.class + Asset.class, Computer.class, Employee.class, + A.class, B.class, C.class }; } }