/* * 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.optimizations.deletebyterm; import javax.persistence.Entity; import javax.persistence.Id; import org.apache.lucene.document.Document; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.junit.Test; import org.junit.experimental.categories.Category; import org.hibernate.search.FullTextSession; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.backend.impl.lucene.WorkspaceHolder; import org.hibernate.search.indexes.spi.DirectoryBasedIndexManager; import org.hibernate.search.spi.SearchIntegrator; import org.hibernate.search.test.util.FullTextSessionBuilder; import org.hibernate.search.testsupport.junit.SkipOnElasticsearch; import static org.fest.assertions.Assertions.assertThat; /** * @author Emmanuel Bernard <emmanuel@hibernate.org> */ @Category(SkipOnElasticsearch.class) // This optimization is specific to the Lucene backend public class DeleteByTermTest { @Test public void testRelatedHierarchiesWithRootNonIndexed() throws Exception { // Create two entities whose root entity is common but not indexed // delete by term should be used // create a unrelated Lucene Document with the same id // it should be deleted when the entity sharing the id is deleted FullTextSessionBuilder sessionBuilder = new FullTextSessionBuilder(); sessionBuilder .addAnnotatedClass( ASubOfRoot.class ) .addAnnotatedClass( BSubOfRoot.class ) .build(); FullTextSession fts = sessionBuilder.openFullTextSession(); fts.beginTransaction(); ASubOfRoot a = new ASubOfRoot(); a.id = "1"; a.name = "Foo"; fts.persist( a ); BSubOfRoot b = new BSubOfRoot(); b.id = "2"; b.otherName = "Bar"; fts.persist( b ); fts.getTransaction().commit(); fts.clear(); // add a document that matches the entity a identifier to see if it is removed when the entity is removed DirectoryBasedIndexManager indexManager = (DirectoryBasedIndexManager) fts.getSearchFactory().unwrap( SearchIntegrator.class ).getIndexManager( "index1" ); WorkspaceHolder backendProcessor = (WorkspaceHolder) indexManager.getWorkspaceHolder(); IndexWriter writer = backendProcessor.getIndexResources().getWorkspace().getIndexWriter(); Document document = new Document(); document.add( new StringField( "id", "1", org.apache.lucene.document.Field.Store.NO ) ); document.add( new TextField( "name", "Baz", org.apache.lucene.document.Field.Store.NO ) ); writer.addDocument( document ); writer.commit(); fts.getTransaction().begin(); fts.delete( fts.get( ASubOfRoot.class, a.id ) ); fts.delete( fts.get( BSubOfRoot.class, b.id ) ); fts.getTransaction().commit(); fts.close(); // Verify that the index is empty IndexReader indexReader = fts.getSearchFactory().getIndexReaderAccessor().open( "index1" ); try { assertThat( indexReader.numDocs() ).isEqualTo( 0 ); } finally { indexReader.close(); } sessionBuilder.close(); } @Test public void testUnrelatedHierarchies() throws Exception { // Create two entities whose root entities are unrelated // delete by term should not be used // create a unrelated Lucene Document with the same id // it should not be deleted when the entity sharing the id is deleted FullTextSessionBuilder sessionBuilder = new FullTextSessionBuilder(); sessionBuilder .addAnnotatedClass( ASubOfRoot.class ) .addAnnotatedClass( Unrelated.class ) .build(); FullTextSession fts = sessionBuilder.openFullTextSession(); fts.beginTransaction(); ASubOfRoot a = new ASubOfRoot(); a.id = "1"; a.name = "Foo"; fts.persist( a ); Unrelated b = new Unrelated(); b.id = "2"; b.name = "Bar"; fts.persist( b ); fts.getTransaction().commit(); fts.clear(); // add a document that matches the entity a identifier to see if it is removed when the entity is removed DirectoryBasedIndexManager indexManager = (DirectoryBasedIndexManager) fts.getSearchFactory().unwrap( SearchIntegrator.class ).getIndexManager( "index1" ); WorkspaceHolder backendProcessor = (WorkspaceHolder) indexManager.getWorkspaceHolder(); IndexWriter writer = backendProcessor.getIndexResources().getWorkspace().getIndexWriter(); Document document = new Document(); document.add( new StringField( "id", "1", org.apache.lucene.document.Field.Store.NO ) ); document.add( new TextField( "name", "Baz", org.apache.lucene.document.Field.Store.NO ) ); writer.addDocument( document ); writer.commit(); fts.getTransaction().begin(); fts.delete( fts.get( ASubOfRoot.class, a.id ) ); fts.delete( fts.get( Unrelated.class, b.id ) ); fts.getTransaction().commit(); fts.close(); // Verify that the index is empty IndexReader indexReader = fts.getSearchFactory().getIndexReaderAccessor().open( "index1" ); try { assertThat( indexReader.numDocs() ).isEqualTo( 1 ); } finally { indexReader.close(); } sessionBuilder.close(); } @Entity public static class RootNonIndexed { @Id public String id; } @Entity @Indexed(index = "index1") public static class ASubOfRoot extends RootNonIndexed { @Field public String name; } @Entity @Indexed(index = "index1") public static class BSubOfRoot extends RootNonIndexed { @Field public String otherName; } @Entity @Indexed(index = "index1") public static class Unrelated { @Id public String id; @Field public String name; } }