/* * Hibernate Search, full-text search for your domain model * * 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.search.test.engine.indexapi; import java.util.Arrays; import java.util.List; import org.apache.lucene.search.MatchAllDocsQuery; import org.hibernate.Criteria; import org.hibernate.Transaction; import org.hibernate.search.FullTextSession; import org.hibernate.search.Search; import org.hibernate.search.test.SearchTestBase; import org.hibernate.search.testsupport.TestForIssue; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Test {@link FullTextSession#purge(Class, java.io.Serializable)} and {@link FullTextSession#purgeAll(Class)}. * * @author John Griffin * @author Hardy Ferentschik */ public class PurgeTest extends SearchTestBase { @Before @Override public void setUp() throws Exception { super.setUp(); indexTestData(); } @Test public void testPurgeById() throws Exception { assertNumberOfIndexedEntitiesForTypes( 2, Clock.class ); assertNumberOfIndexedEntitiesForTypes( 2, Book.class ); FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); Clock clock = getSingleInstanceOfType( fullTextSession, Clock.class ); // purge a single clock instance from the index fullTextSession.purge( Clock.class, clock.getId() ); tx.commit(); fullTextSession.close(); assertNumberOfIndexedEntitiesForTypes( 1, Clock.class ); // only a single clock instance got purged assertNumberOfIndexedEntitiesForTypes( 2, Book.class ); } @Test public void testPurgeAll() throws Exception { assertNumberOfIndexedEntitiesForTypes( 2, Clock.class ); assertNumberOfIndexedEntitiesForTypes( 2, Book.class ); FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); // purge all clocks fullTextSession.purgeAll( Clock.class ); tx.commit(); fullTextSession.close(); assertNumberOfIndexedEntitiesForTypes( 0, Clock.class ); assertNumberOfIndexedEntitiesForTypes( 2, Book.class ); fullTextSession = Search.getFullTextSession( openSession() ); tx = fullTextSession.beginTransaction(); // now purge all books fullTextSession.purgeAll( Book.class ); tx.commit(); fullTextSession.close(); assertNumberOfIndexedEntitiesForTypes( 0, Clock.class ); assertNumberOfIndexedEntitiesForTypes( 0, Book.class ); } @Test @TestForIssue(jiraKey = "HSEARCH-1271") public void testPurgeEntityWithContainedIn() throws Exception { assertNumberOfIndexedEntitiesForTypes( 1, Tree.class ); assertNumberOfIndexedEntitiesForTypes( 4, Leaf.class ); FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); Leaf leave = getSingleInstanceOfType( fullTextSession, Leaf.class ); // purge a single leave fullTextSession.purge( Leaf.class, leave.getId() ); tx.commit(); fullTextSession.close(); assertNumberOfIndexedEntitiesForTypes( 1, Tree.class ); assertNumberOfIndexedEntitiesForTypes( 3, Leaf.class ); } @Test @TestForIssue(jiraKey = "HSEARCH-1271") public void testPurgeAllWithContainedIn() throws Exception { assertNumberOfIndexedEntitiesForTypes( 1, Tree.class ); assertNumberOfIndexedEntitiesForTypes( 4, Leaf.class ); FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); // purge all leaves fullTextSession.purgeAll( Leaf.class ); tx.commit(); fullTextSession.close(); assertNumberOfIndexedEntitiesForTypes( 1, Tree.class ); assertNumberOfIndexedEntitiesForTypes( 0, Leaf.class ); } @Test @TestForIssue(jiraKey = "HSEARCH-1271") public void testPurgeWithNullAsIdDeletesAllIndexedDocuments() throws Exception { assertNumberOfIndexedEntitiesForTypes( 1, Tree.class ); assertNumberOfIndexedEntitiesForTypes( 4, Leaf.class ); FullTextSession fullTextSession = Search.getFullTextSession( openSession() ); Transaction tx = fullTextSession.beginTransaction(); fullTextSession.purge( Leaf.class, null ); tx.commit(); fullTextSession.close(); assertNumberOfIndexedEntitiesForTypes( 1, Tree.class ); assertNumberOfIndexedEntitiesForTypes( 0, Leaf.class ); } @Override public Class<?>[] getAnnotatedClasses() { return new Class[] { Book.class, Clock.class, Author.class, Leaf.class, Tree.class }; } @SuppressWarnings("unchecked") private <T> T getSingleInstanceOfType(FullTextSession fullTextSession, Class<T> type) { Criteria criteria = fullTextSession.createCriteria( type ); criteria.setMaxResults( 1 ); return ( (List<T>) criteria.list() ).get( 0 ); } private void assertNumberOfIndexedEntitiesForTypes(int expectedCount, Class<?>... types) { try ( FullTextSession fullTextSession = Search.getFullTextSession( openSession() ) ) { Transaction tx = fullTextSession.beginTransaction(); org.hibernate.Query query = fullTextSession.createFullTextQuery( new MatchAllDocsQuery(), types ); @SuppressWarnings("unchecked") List<Object> results = (List<Object>) query.list(); assertEquals( "Incorrect document count for type: " + Arrays.toString( types ), expectedCount, results.size() ); tx.commit(); } } private void indexTestData() { try ( FullTextSession fullTextSession = Search.getFullTextSession( openSession() ) ) { Transaction tx = fullTextSession.beginTransaction(); //create a couple of clocks Clock clock = new Clock( 1, "Seiko" ); fullTextSession.save( clock ); clock = new Clock( 2, "Festina" ); fullTextSession.save( clock ); // create a couple of books Book book = new Book( 1, "La chute de la petite reine a travers les yeux de Festina", "La chute de la petite reine a travers les yeux de Festina, blahblah" ); fullTextSession.save( book ); book = new Book( 2, "La gloire de mon père", "Les deboires de mon père en vélo" ); fullTextSession.save( book ); // create and index a tree Tree tree = new Tree( "birch" ); for ( int i = 0; i < 4; i++ ) { tree.growNewLeave(); } fullTextSession.save( tree ); tx.commit(); } } }