HHH-9002 : Fetch many-to-many order by

This commit is contained in:
Gail Badner 2014-03-14 15:57:05 -07:00
parent 7ca36585a9
commit 63881f137e
5 changed files with 307 additions and 2 deletions

View File

@ -571,7 +571,7 @@ public class LoadQueryJoinAndFetchProcessor {
); );
// add SQL ORDER-BY fragments // add SQL ORDER-BY fragments
final String manyToManyOrdering = queryableCollection.getManyToManyOrderByString( collectionTableAlias ); final String manyToManyOrdering = queryableCollection.getManyToManyOrderByString( elementTableAlias );
if ( StringHelper.isNotEmpty( manyToManyOrdering ) ) { if ( StringHelper.isNotEmpty( manyToManyOrdering ) ) {
selectStatementBuilder.appendOrderByFragment( manyToManyOrdering ); selectStatementBuilder.appendOrderByFragment( manyToManyOrdering );
} }

View File

@ -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<B> bs = new ArrayList<B>();
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<B> getBs() {
return bs;
}
// public void setBs(java.util.List<B> bs) {
// this.bs = bs;
// }
@Override
public String toString() {
return "A [id=" + id + ", name=" + name + ", bs=" + bs + "]";
}
}

View File

@ -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<C> cs = new ArrayList<C>();
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<C> getCs() {
return cs;
}
@Override
public String toString() {
return "B [id=" + id + ", name=" + name + ", cs="+cs+"]";
}
}

View File

@ -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 + "]";
}
}

View File

@ -442,6 +442,73 @@ public class OrderByTest extends BaseCoreFunctionalTestCase {
assertEquals( 2, employee.getAssets().get( 1 ).getIdAsset().intValue() ); 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<C> 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<B> bs = a.getBs();
assertEquals( "b1", bs.get( 0 ).getName() );
assertEquals( "b2", bs.get( 1 ).getName() );
List<C> b1cs = bs.get( 0 ).getCs();
assertEquals( 2, b1cs.size() );
assertEquals( "c11", b1cs.get( 0 ).getName() );
assertEquals( "c12", b1cs.get( 1 ).getName() );
List<C> 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 @Override
protected Class[] getAnnotatedClasses() { protected Class[] getAnnotatedClasses() {
@ -450,7 +517,8 @@ public class OrderByTest extends BaseCoreFunctionalTestCase {
Monkey.class, Visitor.class, Box.class, Item.class, Monkey.class, Visitor.class, Box.class, Item.class,
BankAccount.class, Transaction.class, BankAccount.class, Transaction.class,
Comment.class, Forum.class, Post.class, User.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
}; };
} }
} }