/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.hqlfetchscroll;
import org.hibernate.Hibernate;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.transform.DistinctRootEntityResultTransformer;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class HQLScrollFetchTest extends BaseCoreFunctionalTestCase {
private static final String QUERY = "select p from Parent p join fetch p.children c";
@Test
public void testNoScroll() {
Session s = openSession();
s.beginTransaction();
List list = s.createQuery( QUERY ).setResultTransformer( DistinctRootEntityResultTransformer.INSTANCE ).list();
assertResultFromAllUsers( list );
s.getTransaction().commit();
s.close();
}
@Test
public void testScroll() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc, c.name asc" ).scroll();
List list = new ArrayList();
while ( results.next() ) {
list.add( results.get( 0 ) );
}
assertResultFromAllUsers( list );
s.getTransaction().commit();
s.close();
}
@Test
public void testIncompleteScrollFirstResult() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
results.next();
Parent p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
s.getTransaction().commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testIncompleteScrollSecondResult() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
results.next();
Parent p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
results.next();
p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
s.getTransaction().commit();
s.close();
}
@Test
public void testIncompleteScrollFirstResultInTransaction() {
Session s = openSession();
Transaction tx = s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
results.next();
Parent p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
tx.commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testIncompleteScrollSecondResultInTransaction() {
Session s = openSession();
Transaction tx = s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
results.next();
Parent p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
results.next();
p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
tx.commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283")
public void testIncompleteScroll() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
results.next();
Parent p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
// get the other parent entity from the persistence context along with its first child
// retrieved from the resultset.
Parent pOther = null;
Child cOther = null;
for ( Object entity : ( (SessionImplementor) s ).getPersistenceContext().getEntitiesByKey().values() ) {
if ( Parent.class.isInstance( entity ) ) {
if ( entity != p ) {
if ( pOther != null ) {
fail( "unexpected parent found." );
}
pOther = (Parent) entity;
}
}
else if ( Child.class.isInstance( entity ) ) {
if ( ! p.getChildren().contains( entity ) ) {
if ( cOther != null ) {
fail( "unexpected child entity found" );
}
cOther = (Child) entity;
}
}
else {
fail( "unexpected type of entity." );
}
}
// check that the same second parent is obtained by calling Session.get()
assertNull( pOther );
assertNull( cOther );
s.getTransaction().commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testIncompleteScrollLast() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
results.next();
Parent p = (Parent) results.get( 0 );
assertResultFromOneUser( p );
results.last();
// get the other parent entity from the persistence context.
// since the result set was scrolled to the end, the other parent entity's collection has been
// properly initialized.
Parent pOther = null;
Set childrenOther = new HashSet();
for ( Object entity : ( ( SessionImplementor) s ).getPersistenceContext().getEntitiesByKey().values() ) {
if ( Parent.class.isInstance( entity ) ) {
if ( entity != p ) {
if ( pOther != null ) {
fail( "unexpected parent found." );
}
pOther = (Parent) entity;
}
}
else if ( Child.class.isInstance( entity ) ) {
if ( ! p.getChildren().contains( entity ) ) {
childrenOther.add( entity );
}
}
else {
fail( "unexpected type of entity." );
}
}
// check that the same second parent is obtained by calling Session.get()
assertNotNull( pOther );
assertSame( pOther, s.get( Parent.class, pOther.getId() ) );
// access pOther's collection; should be completely loaded
assertTrue( Hibernate.isInitialized( pOther.getChildren() ) );
assertEquals( childrenOther, pOther.getChildren() );
assertResultFromOneUser( pOther );
s.getTransaction().commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testScrollOrderParentAsc() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc" ).scroll();
List list = new ArrayList();
while ( results.next() ) {
list.add( results.get( 0 ) );
}
assertResultFromAllUsers( list );
s.getTransaction().commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testScrollOrderParentDesc() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name desc" ).scroll();
List list = new ArrayList();
while ( results.next() ) {
list.add( results.get( 0 ) );
}
assertResultFromAllUsers( list );
s.getTransaction().commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testScrollOrderParentAscChildrenAsc() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc, c.name asc" ).scroll();
List list = new ArrayList();
while ( results.next() ) {
list.add( results.get( 0 ) );
}
assertResultFromAllUsers( list );
s.getTransaction().commit();
s.close();
}
@Test
@TestForIssue( jiraKey = "HHH-1283" )
public void testScrollOrderParentAscChildrenDesc() {
Session s = openSession();
s.beginTransaction();
ScrollableResults results = s.createQuery( QUERY + " order by p.name asc, c.name desc" ).scroll();
List list = new ArrayList();
while ( results.next() ) {
list.add( results.get( 0 ) );
}
assertResultFromAllUsers( list );
s.getTransaction().commit();
s.close();
}
@Test
public void testScrollOrderChildrenDesc() {
Session s = openSession();
Transaction t = s.beginTransaction();
Parent p0 = new Parent( "parent0" );
s.save( p0 );
t.commit();
s.close();
s = openSession();
ScrollableResults results = s.createQuery( QUERY + " order by c.name desc" ).scroll();
List list = new ArrayList();
while ( results.next() ) {
list.add( results.get( 0 ) );
}
try {
assertResultFromAllUsers( list );
fail( "should have failed because data is ordered incorrectly." );
}
catch ( AssertionError ex ) {
// expected
}
finally {
s.close();
}
}
@Test
public void testListOrderChildrenDesc() {
Session s = openSession();
Transaction t = s.beginTransaction();
Parent p0 = new Parent( "parent0" );
s.save( p0 );
t.commit();
s.close();
s = openSession();
List results = s.createQuery( QUERY + " order by c.name desc" ).list();
try {
assertResultFromAllUsers( results );
fail( "should have failed because data is ordered incorrectly." );
}
catch ( AssertionError ex ) {
// expected
}
finally {
s.close();
}
}
private void assertResultFromOneUser(Parent parent) {
assertEquals(
"parent " + parent + " has incorrect collection(" + parent.getChildren() + ").",
3,
parent.getChildren().size()
);
}
private void assertResultFromAllUsers(List list) {
assertEquals( "list is not correct size: ", 2, list.size() );
for ( Object aList : list ) {
assertResultFromOneUser( (Parent) aList );
}
}
@Override
protected void prepareTest() throws Exception {
Session s = openSession();
Transaction t = s.beginTransaction();
Child child_1_1 = new Child( "achild1-1");
Child child_1_2 = new Child( "ychild1-2");
Child child_1_3 = new Child( "dchild1-3");
Child child_2_1 = new Child( "bchild2-1");
Child child_2_2 = new Child( "cchild2-2");
Child child_2_3 = new Child( "zchild2-3");
s.save( child_1_1 );
s.save( child_2_1 );
s.save( child_1_2 );
s.save( child_2_2 );
s.save( child_1_3 );
s.save( child_2_3 );
s.flush();
Parent p1 = new Parent( "parent1" );
p1.addChild( child_1_1 );
p1.addChild( child_1_2 );
p1.addChild( child_1_3 );
s.save( p1 );
Parent p2 = new Parent( "parent2" );
p2.addChild( child_2_1 );
p2.addChild( child_2_2 );
p2.addChild( child_2_3 );
s.save( p2 );
t.commit();
s.close();
}
@Override
protected void cleanupTest() throws Exception {
Session s = openSession();
Transaction t = s.beginTransaction();
List list = s.createQuery( "from Parent" ).list();
for ( Iterator i = list.iterator(); i.hasNext(); ) {
s.delete( i.next() );
}
t.commit();
s.close();
}
public String[] getMappings() {
return new String[] { "hqlfetchscroll/ParentChild.hbm.xml" };
}
}