/* * 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.worker.duplication; import java.util.List; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.TopDocs; import org.hibernate.Transaction; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.SearchFactory; import org.hibernate.search.backend.AddLuceneWork; import org.hibernate.search.backend.LuceneWork; import org.hibernate.search.backend.spi.Work; import org.hibernate.search.backend.impl.WorkQueue; import org.hibernate.search.backend.spi.WorkType; import org.hibernate.search.engine.spi.SearchFactoryImplementor; import org.hibernate.search.test.SearchTestCase; import org.hibernate.search.test.TestConstants; /** * Testcase for HSEARCH-257. */ public class WorkDuplicationTest extends SearchTestCase { /** * This test assures that HSEARCH-257. Before the fix Search would issue another <code>AddLuceneWork</code> after * the <code>DeleteLuceneWork</code>. This lead to the fact that after the deletion there was still a Lucene document * in the index. * * @throws Exception in case the test fails. */ public void testNoWorkDuplication() throws Exception { FullTextSession s = org.hibernate.search.Search.getFullTextSession( openSession() ); Transaction tx = s.beginTransaction(); // create new customer SpecialPerson person = new SpecialPerson(); person.setName( "Joe Smith" ); EmailAddress emailAddress = new EmailAddress(); emailAddress.setAddress( "foo@foobar.com" ); emailAddress.setDefaultAddress(true); person.addEmailAddress( emailAddress ); // persist the customer s.persist( person ); tx.commit(); // search if the record made it into the index tx = s.beginTransaction(); String searchQuery = "Joe"; QueryParser parser = new QueryParser( TestConstants.getTargetLuceneVersion(), "Content", TestConstants.standardAnalyzer ); Query luceneQuery = parser.parse( searchQuery ); FullTextQuery query = s.createFullTextQuery( luceneQuery ); List results = query.list(); assertTrue( "We should have a hit", results.size() == 1 ); tx.commit(); // Now try to delete tx = s.beginTransaction(); int id = person.getId(); person = ( SpecialPerson ) s.get( SpecialPerson.class, id ); s.delete( person ); tx.commit(); // Search and the record via Lucene directly tx = s.beginTransaction(); SearchFactory searchFactory = s.getSearchFactory(); IndexReader indexReader = searchFactory.getIndexReaderAccessor().open( SpecialPerson.class ); try { IndexSearcher searcher = new IndexSearcher( indexReader ); // we have to test using Lucene directly since query loaders will ignore hits for which there is no // database entry TopDocs topDocs = searcher.search( luceneQuery, null, 1 ); assertTrue( "We should have no hit", topDocs.totalHits == 0 ); } finally { searchFactory.getIndexReaderAccessor().close( indexReader ); } tx.commit(); s.close(); } /** * Tests that adding and deleting the same entity only results into a single delete in the work queue. * See HSEARCH-293. * * @throws Exception in case the test fails. */ public void testAddWorkGetReplacedByDeleteWork() throws Exception { FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession( openSession() ); SearchFactoryImplementor searchFactory = ( SearchFactoryImplementor ) fullTextSession.getSearchFactory(); // create test entity SpecialPerson person = new SpecialPerson(); person.setName( "Joe Smith" ); EmailAddress emailAddress = new EmailAddress(); emailAddress.setAddress( "foo@foobar.com" ); emailAddress.setDefaultAddress(true); person.addEmailAddress( emailAddress ); WorkQueue plannerEngine = new WorkQueue( searchFactory ); plannerEngine.add( new Work<SpecialPerson>( person, 1, WorkType.ADD ) ); plannerEngine.prepareWorkPlan(); List<LuceneWork> sealedQueue = plannerEngine.getSealedQueue(); assertEquals("There should only be one job in the queue", 1, sealedQueue.size()); assertTrue("Wrong job type", sealedQueue.get(0) instanceof AddLuceneWork ); plannerEngine.add( new Work<SpecialPerson>( person, 1, WorkType.DELETE ) ); plannerEngine.prepareWorkPlan(); sealedQueue = plannerEngine.getSealedQueue(); assertEquals("Jobs should have countered each other", 0, sealedQueue.size()); fullTextSession.close(); } protected Class<?>[] getAnnotatedClasses() { return new Class[] { Person.class, EmailAddress.class, SpecialPerson.class }; } }