HHH-10874 - @Where annotation is not processed with "Extra-lazy" loading for bidirectional collections
For bidirectional collections, the where clause is now considered when calculating the size() of the LazyCollectionOption.EXTRA annotated collections
This commit is contained in:
parent
eec01edcca
commit
253820a289
|
@ -1012,6 +1012,7 @@ public abstract class AbstractCollectionPersister
|
|||
return new SimpleSelect( dialect )
|
||||
.setTableName( getTableName() )
|
||||
.addCondition( getKeyColumnNames(), "=?" )
|
||||
.addWhereToken( sqlWhereString )
|
||||
.addColumn( selectValue )
|
||||
.toStatementString();
|
||||
}
|
||||
|
@ -1025,6 +1026,7 @@ public abstract class AbstractCollectionPersister
|
|||
.addCondition( getKeyColumnNames(), "=?" )
|
||||
.addCondition( getIndexColumnNames(), "=?" )
|
||||
.addCondition( indexFormulas, "=?" )
|
||||
.addWhereToken( sqlWhereString )
|
||||
.addColumn( "1" )
|
||||
.toStatementString();
|
||||
}
|
||||
|
@ -1038,6 +1040,7 @@ public abstract class AbstractCollectionPersister
|
|||
.addCondition( getKeyColumnNames(), "=?" )
|
||||
.addCondition( getIndexColumnNames(), "=?" )
|
||||
.addCondition( indexFormulas, "=?" )
|
||||
.addWhereToken( sqlWhereString )
|
||||
.addColumns( getElementColumnNames(), elementColumnAliases )
|
||||
.addColumns( indexFormulas, indexColumnAliases )
|
||||
.toStatementString();
|
||||
|
@ -1049,6 +1052,7 @@ public abstract class AbstractCollectionPersister
|
|||
.addCondition( getKeyColumnNames(), "=?" )
|
||||
.addCondition( getElementColumnNames(), "=?" )
|
||||
.addCondition( elementFormulas, "=?" )
|
||||
.addWhereToken( sqlWhereString )
|
||||
.addColumn( "1" )
|
||||
.toStatementString();
|
||||
}
|
||||
|
|
|
@ -96,7 +96,12 @@ public class SimpleSelect {
|
|||
}
|
||||
|
||||
public SimpleSelect addWhereToken(String token) {
|
||||
whereTokens.add( token );
|
||||
if (token != null ) {
|
||||
if (!whereTokens.isEmpty()) {
|
||||
and();
|
||||
}
|
||||
whereTokens.add( token );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package org.hibernate.test.extralazy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.hibernate.annotations.Where;
|
||||
|
||||
@Entity
|
||||
@Table(name = "championship")
|
||||
public class Championship {
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@LazyCollection(LazyCollectionOption.EXTRA)
|
||||
@Where(clause = " gpa >= 4 ")
|
||||
private List<Student> students = new ArrayList<>();
|
||||
|
||||
public Championship() {}
|
||||
|
||||
public Championship(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Student> getStudents() {
|
||||
return students;
|
||||
}
|
||||
}
|
|
@ -5,11 +5,6 @@
|
|||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.extralazy;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -19,11 +14,18 @@ import org.hibernate.Session;
|
|||
import org.hibernate.Transaction;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -33,6 +35,11 @@ public class ExtraLazyTest extends BaseCoreFunctionalTestCase {
|
|||
return new String[] { "extralazy/UserGroup.hbm.xml","extralazy/Parent.hbm.xml","extralazy/Child.hbm.xml" };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { School.class, Student.class, Championship.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrphanDelete() {
|
||||
Session s = openSession();
|
||||
|
@ -248,5 +255,90 @@ public class ExtraLazyTest extends BaseCoreFunctionalTestCase {
|
|||
assertNotNull(child2);
|
||||
session2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10874")
|
||||
public void testWhereClauseOnBidirectionalCollection() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
|
||||
School school = new School(1);
|
||||
s.persist(school);
|
||||
|
||||
Student gavin = new Student("gavin", 4);
|
||||
Student turin = new Student("turin", 3);
|
||||
Student mike = new Student("mike", 5);
|
||||
Student fred = new Student("fred", 2);
|
||||
|
||||
gavin.setSchool(school);
|
||||
turin.setSchool(school);
|
||||
mike.setSchool(school);
|
||||
fred.setSchool(school);
|
||||
|
||||
s.persist(gavin);
|
||||
s.persist(turin);
|
||||
s.persist(mike);
|
||||
s.persist(fred);
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
School school2 = s.get(School.class, 1);
|
||||
|
||||
assertEquals(4, school2.getStudents().size());
|
||||
|
||||
assertEquals( 2, school2.getTopStudents().size() );
|
||||
assertTrue( school2.getTopStudents().contains( gavin ) );
|
||||
assertTrue( school2.getTopStudents().contains( mike ) );
|
||||
|
||||
assertEquals(2, school2.getStudentsMap().size() );
|
||||
assertTrue( school2.getStudentsMap().containsKey( gavin.getId() ) );
|
||||
assertTrue( school2.getStudentsMap().containsKey( mike.getId() ) );
|
||||
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( jiraKey = "HHH-3319" )
|
||||
public void testWhereClauseOnUnidirectionalCollection() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
|
||||
Championship championship = new Championship( 1 );
|
||||
s.persist(championship);
|
||||
|
||||
Student gavin = new Student("gavin", 4);
|
||||
Student turin = new Student("turin", 3);
|
||||
Student mike = new Student("mike", 5);
|
||||
Student fred = new Student("fred", 2);
|
||||
|
||||
championship.getStudents().add( gavin );
|
||||
championship.getStudents().add( turin );
|
||||
championship.getStudents().add( mike );
|
||||
championship.getStudents().add( fred );
|
||||
|
||||
s.persist(gavin);
|
||||
s.persist(turin);
|
||||
s.persist(mike);
|
||||
s.persist(fred);
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
|
||||
Championship championship2 = s.get(Championship.class, 1);
|
||||
assertEquals( 2, championship2.getStudents().size() );
|
||||
assertTrue( championship2.getStudents().contains( gavin ) );
|
||||
assertTrue( championship2.getStudents().contains( mike ) );
|
||||
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean rebuildSessionFactoryOnError() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package org.hibernate.test.extralazy;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MapKey;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.hibernate.annotations.Where;
|
||||
|
||||
@Entity
|
||||
@Table(name = "school")
|
||||
public class School {
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@OneToMany(mappedBy = "school")
|
||||
@LazyCollection(LazyCollectionOption.EXTRA)
|
||||
private Set<Student> students = new HashSet<Student>();
|
||||
|
||||
@OneToMany(mappedBy = "school")
|
||||
@LazyCollection(LazyCollectionOption.EXTRA)
|
||||
@Where(clause = " gpa >= 4 ")
|
||||
private Set<Student> topStudents = new HashSet<Student>();
|
||||
|
||||
@OneToMany(mappedBy = "school")
|
||||
@LazyCollection(LazyCollectionOption.EXTRA)
|
||||
@Where(clause = " gpa >= 4 ")
|
||||
@MapKey
|
||||
private Map<String, Student> studentsMap = new HashMap<>();
|
||||
|
||||
public School() {}
|
||||
|
||||
public School(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Set<Student> getStudents() {
|
||||
return students;
|
||||
}
|
||||
|
||||
public Set<Student> getTopStudents() {
|
||||
return topStudents;
|
||||
}
|
||||
|
||||
public Map<String, Student> getStudentsMap() {
|
||||
return studentsMap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package org.hibernate.test.extralazy;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import static javax.persistence.GenerationType.IDENTITY;
|
||||
|
||||
@Entity
|
||||
@Table(name = "student")
|
||||
public class Student {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = IDENTITY)
|
||||
private String id;
|
||||
|
||||
@ManyToOne
|
||||
private School school;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private int gpa;
|
||||
|
||||
public Student() {}
|
||||
|
||||
public Student(String firstName, int gpa) {
|
||||
this.firstName = firstName;
|
||||
this.gpa = gpa;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public School getSchool() {
|
||||
return school;
|
||||
}
|
||||
|
||||
public void setSchool(School school) {
|
||||
this.school = school;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public int getGpa() {
|
||||
return gpa;
|
||||
}
|
||||
|
||||
public void setGpa(int gpa) {
|
||||
this.gpa = gpa;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( !( o instanceof Student ) ) {
|
||||
return false;
|
||||
}
|
||||
Student student = (Student) o;
|
||||
return Objects.equals( getFirstName(), student.getFirstName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( getFirstName() );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue