Java tutorial
/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, Red Hat, Inc. and/or its affiliates 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.search.test.query; import org.apache.lucene.index.Term; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermQuery; import org.hibernate.ScrollableResults; import org.hibernate.Transaction; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.test.util.FullTextSessionBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; /** * Test for org.hibernate.search.query.ScrollableResultsImpl * * @see org.hibernate.search.query.hibernate.impl.ScrollableResultsImpl * @author Sanne Grinovero */ public class ScrollableResultsTest { private FullTextSessionBuilder builder; private FullTextSession sess; @Before public void setUp() { builder = new FullTextSessionBuilder(); builder.addAnnotatedClass(AlternateBook.class).addAnnotatedClass(Employee.class) .setProperty("hibernate.default_batch_fetch_size", "10").build(); sess = builder.openFullTextSession(); Transaction tx = sess.beginTransaction(); //create some entities to query: for (int i = 0; i < 324; i++) { sess.persist(new AlternateBook(i, "book about the number " + i)); } for (int i = 0; i < 133; i++) { sess.persist(new Employee(i, "Rossi", "dept. num. " + i)); } tx.commit(); } @After public void tearDown() { builder.close(); } /** * Test forward scrolling using pagination */ @Test public void testScrollingForward() { Transaction tx = sess.beginTransaction(); TermQuery tq = new TermQuery(new Term("summary", "number")); Sort sort = new Sort(new SortField("id", SortField.STRING)); ScrollableResults scrollableResults = sess.createFullTextQuery(tq, AlternateBook.class).setSort(sort) .setFetchSize(10).setFirstResult(20).setMaxResults(111).scroll(); assertEquals(-1, scrollableResults.getRowNumber()); assertTrue(scrollableResults.last()); assertEquals(110, scrollableResults.getRowNumber()); scrollableResults.beforeFirst(); int position = scrollableResults.getRowNumber(); while (scrollableResults.next()) { position++; int bookId = position + 20; assertEquals(position, scrollableResults.getRowNumber()); AlternateBook book = (AlternateBook) scrollableResults.get()[0]; assertEquals(bookId, book.getId().intValue()); assertEquals("book about the number " + bookId, book.getSummary()); assertTrue(sess.contains(book)); } assertEquals(110, position); scrollableResults.close(); tx.commit(); } /** * Verify inverse-order scrolling. * TODO to verify correct FetchSize behavior I've been debugging * the behavior; we should add a mock library to automate this kind of tests. */ @Test public void testScrollingBackwards() { Transaction tx = sess.beginTransaction(); TermQuery tq = new TermQuery(new Term("summary", "number")); Sort sort = new Sort(new SortField("id", SortField.STRING)); ScrollableResults scrollableResults = sess.createFullTextQuery(tq, AlternateBook.class).setSort(sort) .setFetchSize(10).scroll(); scrollableResults.beforeFirst(); // initial position should be -1 as in Hibernate Core assertEquals(-1, scrollableResults.getRowNumber()); assertTrue(scrollableResults.last()); int position = scrollableResults.getRowNumber(); assertEquals(323, position); while (scrollableResults.previous()) { AlternateBook book = (AlternateBook) scrollableResults.get()[0]; assertEquals(--position, book.getId().intValue()); assertEquals("book about the number " + position, book.getSummary()); } assertEquals(0, position); assertEquals(-1, scrollableResults.getRowNumber()); scrollableResults.close(); tx.commit(); } /** * Test that all entities returned by a ScrollableResults * are always attached to Session */ @Test public void testResultsAreManaged() { Transaction tx = sess.beginTransaction(); TermQuery tq = new TermQuery(new Term("summary", "number")); Sort sort = new Sort(new SortField("id", SortField.STRING)); ScrollableResults scrollableResults = sess.createFullTextQuery(tq, AlternateBook.class).setSort(sort) .setFetchSize(10).scroll(); int position = -1; while (scrollableResults.next()) { position++; AlternateBook book = (AlternateBook) scrollableResults.get()[0]; assertTrue(sess.contains(book)); // evict some entities: if (position % 3 == 0) { sess.evict(book); assertFalse(sess.contains(book)); } } //verifies it did scroll to the end: assertEquals(323, position); //assert the entities are re-attached after eviction: while (scrollableResults.previous()) { position--; AlternateBook book = (AlternateBook) scrollableResults.get()[0]; assertTrue(sess.contains(book)); } assertEquals(-1, position); sess.clear(); //assert the entities are re-attached after Session.clear: while (scrollableResults.next()) { position++; AlternateBook book = (AlternateBook) scrollableResults.get()[0]; assertTrue(sess.contains(book)); } assertEquals(323, position); tx.commit(); } /** * Verify scrolling works correctly when combined with Projection * and that the projected entities are managed, even in case * of evict usage for memory management. */ @Test public void testScrollProjectionAndManaged() { Transaction tx = sess.beginTransaction(); TermQuery tq = new TermQuery(new Term("dept", "num")); //the tests relies on the results being returned sorted by id: Sort sort = new Sort(new SortField("id", SortField.STRING)); ScrollableResults scrollableResults = sess.createFullTextQuery(tq, Employee.class) .setProjection(FullTextQuery.OBJECT_CLASS, FullTextQuery.ID, FullTextQuery.THIS, "lastname", FullTextQuery.THIS) .setFetchSize(10).setSort(sort).scroll(); scrollableResults.last(); assertEquals(132, scrollableResults.getRowNumber()); scrollableResults.beforeFirst(); assertEquals(-1, scrollableResults.getRowNumber()); int position = scrollableResults.getRowNumber(); while (scrollableResults.next()) { position++; Object[] objs = scrollableResults.get(); assertEquals(Employee.class, objs[0]); assertEquals(position, objs[1]); assertTrue(objs[2] instanceof Employee); sess.contains(objs[2]); assertEquals("Rossi", objs[3]); assertTrue(objs[4] instanceof Employee); sess.contains(objs[4]); assertTrue(objs[2] == objs[4]); //projected twice the same entity // detach some objects: if (position % 3 == 0) { sess.evict(objs[2]); } } //verify we scrolled to the end: assertEquals(132, position); // and now the other way around, checking entities are attached again: while (scrollableResults.previous()) { position--; Object[] objs = scrollableResults.get(); assertTrue(objs[2] instanceof Employee); sess.contains(objs[2]); assertTrue(objs[4] instanceof Employee); sess.contains(objs[4]); assertTrue(objs[2] == objs[4]); } assertEquals(-1, position); scrollableResults.close(); tx.commit(); } }