/* * 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.batchindexing; import java.util.Set; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.index.Term; import org.apache.lucene.search.TermQuery; import org.junit.Test; import org.hibernate.Transaction; import org.hibernate.search.Environment; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.engine.spi.SearchFactoryImplementor; import org.hibernate.search.impl.MassIndexerImpl; import org.hibernate.search.test.util.FullTextSessionBuilder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class SearchIndexerTest { /** * test that the MassIndexer is properly identifying the root entities * from the selection of classes to be indexed. */ @Test public void testEntityHierarchy() { FullTextSessionBuilder ftsb = new FullTextSessionBuilder() .addAnnotatedClass( ModernBook.class ) .addAnnotatedClass( AncientBook.class ) .addAnnotatedClass( Dvd.class ) .addAnnotatedClass( Book.class ) .addAnnotatedClass( Nation.class ) .build(); FullTextSession fullTextSession = ftsb.openFullTextSession(); SearchFactoryImplementor searchFactory = (SearchFactoryImplementor) fullTextSession.getSearchFactory(); { TestableMassIndexerImpl tsii = new TestableMassIndexerImpl( searchFactory, Book.class ); assertTrue( tsii.getRootEntities().contains( Book.class ) ); assertFalse( tsii.getRootEntities().contains( ModernBook.class ) ); assertFalse( tsii.getRootEntities().contains( AncientBook.class ) ); } { TestableMassIndexerImpl tsii = new TestableMassIndexerImpl( searchFactory, ModernBook.class, AncientBook.class, Book.class ); assertTrue( tsii.getRootEntities().contains( Book.class ) ); assertFalse( tsii.getRootEntities().contains( ModernBook.class ) ); assertFalse( tsii.getRootEntities().contains( AncientBook.class ) ); } { TestableMassIndexerImpl tsii = new TestableMassIndexerImpl( searchFactory, ModernBook.class, AncientBook.class ); assertFalse( tsii.getRootEntities().contains( Book.class ) ); assertTrue( tsii.getRootEntities().contains( ModernBook.class ) ); assertTrue( tsii.getRootEntities().contains( AncientBook.class ) ); } //verify that indexing Object will result in one separate indexer working per root indexed entity { TestableMassIndexerImpl tsii = new TestableMassIndexerImpl( searchFactory, Object.class ); assertTrue( tsii.getRootEntities().contains( Book.class ) ); assertTrue( tsii.getRootEntities().contains( Dvd.class ) ); assertFalse( tsii.getRootEntities().contains( AncientBook.class ) ); assertFalse( tsii.getRootEntities().contains( Object.class ) ); assertEquals( 2, tsii.getRootEntities().size() ); } fullTextSession.close(); ftsb.close(); } private static class TestableMassIndexerImpl extends MassIndexerImpl { protected TestableMassIndexerImpl(SearchFactoryImplementor searchFactory, Class<?>... types) { super( searchFactory, null, types ); } public Set<Class<?>> getRootEntities() { return this.rootEntities; } } // Test to verify that the identifier loading works even when // the property is not called "id" - see HSEARCH-901 @Test public void testIdentifierNaming() throws InterruptedException { //disable automatic indexing, to test manual index creation. FullTextSessionBuilder ftsb = new FullTextSessionBuilder() .setProperty( org.hibernate.search.Environment.ANALYZER_CLASS, StandardAnalyzer.class.getName() ) .addAnnotatedClass( Dvd.class ) .addAnnotatedClass( Nation.class ) .addAnnotatedClass( Book.class ) .addAnnotatedClass( WeirdlyIdentifiedEntity.class ) .setProperty( Environment.INDEXING_STRATEGY, "manual" ) .build(); { //creating the test data in database only: FullTextSession fullTextSession = ftsb.openFullTextSession(); Transaction transaction = fullTextSession.beginTransaction(); Nation us = new Nation( "United States of America", "US" ); fullTextSession.persist( us ); Dvd dvda = new Dvd(); dvda.setTitle( "Star Trek (episode 96367)" ); dvda.setFirstPublishedIn( us ); fullTextSession.save( dvda ); Dvd dvdb = new Dvd(); dvdb.setTitle( "The Trek" ); dvdb.setFirstPublishedIn( us ); fullTextSession.save( dvdb ); WeirdlyIdentifiedEntity entity = new WeirdlyIdentifiedEntity(); entity.setId( "not an identifier" ); fullTextSession.save( entity ); transaction.commit(); fullTextSession.close(); } { //verify index is still empty: assertEquals( 0, countResults( new Term( "title", "trek" ), ftsb, Dvd.class ) ); assertEquals( 0, countResults( new Term( "id", "not" ), ftsb, WeirdlyIdentifiedEntity.class ) ); } { FullTextSession fullTextSession = ftsb.openFullTextSession(); fullTextSession.createIndexer( Dvd.class ) .startAndWait(); fullTextSession.close(); } { //verify index is now containing both DVDs: assertEquals( 2, countResults( new Term( "title", "trek" ), ftsb, Dvd.class ) ); } { FullTextSession fullTextSession = ftsb.openFullTextSession(); fullTextSession.createIndexer( WeirdlyIdentifiedEntity.class ) .startAndWait(); fullTextSession.close(); } { //verify index is now containing the weirdly identified entity: assertEquals( 1, countResults( new Term( "id", "identifier" ), ftsb, WeirdlyIdentifiedEntity.class ) ); } ftsb.close(); } @Test public void testExtendedIdentifierNaming() throws InterruptedException { //disable automatic indexing, to test manual index creation. FullTextSessionBuilder ftsb = new FullTextSessionBuilder() .setProperty( org.hibernate.search.Environment.ANALYZER_CLASS, StandardAnalyzer.class.getName() ) .addAnnotatedClass( ExtendedIssueEntity.class ) .addAnnotatedClass( IssueEntity.class ) .setProperty( Environment.INDEXING_STRATEGY, "manual" ) .build(); { //creating the test data in database only: FullTextSession fullTextSession = ftsb.openFullTextSession(); Transaction transaction = fullTextSession.beginTransaction(); ExtendedIssueEntity issue = new ExtendedIssueEntity(); issue.jiraCode = "HSEARCH-977"; issue.jiraDescription = "MassIndexer freezes when there is an indexed 'id' filed, which is not document's id"; issue.id = 1l; fullTextSession.persist( issue ); transaction.commit(); fullTextSession.close(); } { //verify index is still empty: assertEquals( 0, countResults( new Term( "jiraDescription", "freezes" ), ftsb, ExtendedIssueEntity.class ) ); assertEquals( 0, countResults( new Term( "jiraCode", "HSEARCH" ), ftsb, ExtendedIssueEntity.class ) ); } { FullTextSession fullTextSession = ftsb.openFullTextSession(); fullTextSession.createIndexer( ExtendedIssueEntity.class ) .startAndWait(); fullTextSession.close(); } { //verify index via term readers: assertEquals( 1, countResults( new Term( "jiraDescription", "freezes" ), ftsb, ExtendedIssueEntity.class ) ); assertEquals( 1, countResults( new Term( "id", "1" ), ftsb, ExtendedIssueEntity.class ) ); } } //helper method private int countResults(Term termForQuery, FullTextSessionBuilder ftSessionBuilder, Class<?> type) { TermQuery fullTextQuery = new TermQuery( termForQuery ); FullTextSession fullTextSession = ftSessionBuilder.openFullTextSession(); Transaction transaction = fullTextSession.beginTransaction(); FullTextQuery query = fullTextSession.createFullTextQuery( fullTextQuery, type ); int resultSize = query.getResultSize(); transaction.commit(); fullTextSession.close(); return resultSize; } }