/*
* 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.batchindexing;
import java.util.Set;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.junit.Test;
import org.hibernate.Transaction;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.batchindexing.impl.MassIndexerImpl;
import org.hibernate.search.cfg.Environment;
import org.hibernate.search.spi.SearchIntegrator;
import org.hibernate.search.test.util.FullTextSessionBuilder;
import org.hibernate.search.testsupport.TestForIssue;
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();
SearchIntegrator integrator = fullTextSession.getSearchFactory().unwrap( SearchIntegrator.class );
{
TestableMassIndexerImpl tsii = new TestableMassIndexerImpl( integrator, Book.class );
assertTrue( tsii.getRootEntities().contains( Book.class ) );
assertFalse( tsii.getRootEntities().contains( ModernBook.class ) );
assertFalse( tsii.getRootEntities().contains( AncientBook.class ) );
}
{
TestableMassIndexerImpl tsii = new TestableMassIndexerImpl(
integrator,
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(
integrator,
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( integrator, 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(SearchIntegrator integrator, Class<?>... types) {
super( integrator, 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"
@Test
@TestForIssue(jiraKey = "HSEARCH-901")
public void testIdentifierNaming() throws InterruptedException {
//disable automatic indexing, to test manual index creation.
FullTextSessionBuilder ftsb = new FullTextSessionBuilder()
.setProperty( 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 TermQuery( new Term( "title", "trek" ) ), ftsb, Dvd.class ) );
assertEquals(
0, countResults( new TermQuery( 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 TermQuery( 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 TermQuery( 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( 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 TermQuery( new Term( "jiraDescription", "freezes" ) ), ftsb, ExtendedIssueEntity.class
)
);
assertEquals(
0,
countResults( new TermQuery( 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 TermQuery( new Term( "jiraDescription", "freezes" ) ), ftsb, ExtendedIssueEntity.class
)
);
assertEquals(
1,
countResults(
NumericRangeQuery.newLongRange( "id", 1l, 1l, true, true ), ftsb, ExtendedIssueEntity.class
)
);
}
ftsb.close();
}
//helper method
private int countResults(Query query, FullTextSessionBuilder ftSessionBuilder, Class<?> type) {
FullTextSession fullTextSession = ftSessionBuilder.openFullTextSession();
Transaction transaction = fullTextSession.beginTransaction();
FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery( query, type );
int resultSize = fullTextQuery.getResultSize();
transaction.commit();
fullTextSession.close();
return resultSize;
}
}