/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * 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.ogm.backendtck.massindex; import static org.fest.assertions.Assertions.assertThat; import static org.hibernate.ogm.utils.GridDialectType.MONGODB; import java.util.Arrays; import java.util.List; import javax.persistence.EntityManager; import org.apache.lucene.search.Query; import org.hibernate.ogm.backendtck.id.NewsID; import org.hibernate.ogm.backendtck.massindex.model.IndexedLabel; import org.hibernate.ogm.backendtck.massindex.model.IndexedNews; import org.hibernate.ogm.utils.SkipByGridDialect; import org.hibernate.ogm.utils.jpa.GetterPersistenceUnitInfo; import org.hibernate.ogm.utils.jpa.OgmJpaTestCase; import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.Search; import org.hibernate.search.query.dsl.QueryBuilder; import org.junit.Test; /** * @author Davide D'Alto <davide@hibernate.org> */ public class AssociationMassIndexerTest extends OgmJpaTestCase { @Test @SkipByGridDialect(value = { MONGODB }, comment = "Uses embedded key which is currently not supported by the db query parsers") public void testEntityWithAssociationMassIndexing() throws Exception { populateDatastore(); purgeAll( IndexedNews.class, IndexedLabel.class ); startAndWaitMassIndexing( IndexedNews.class, IndexedLabel.class ); assertEntityHasBeenIndexed(); assertAssociatedElementsHaveBeenIndexed(); } private void populateDatastore() throws Exception { List<IndexedLabel> labes = Arrays.asList( new IndexedLabel( "massindex" ), new IndexedLabel( "test" ) ); IndexedNews news = new IndexedNews( new NewsID( "title", "author" ), "content" ); news.setLabels( labes ); EntityManager em = createEntityManager(); em.getTransaction().begin(); em.persist( news ); em.getTransaction().commit(); em.close(); } private void assertEntityHasBeenIndexed() throws Exception { FullTextEntityManager fullTextEm = Search.getFullTextEntityManager( createEntityManager() ); fullTextEm.getTransaction().begin(); QueryBuilder queryBuilder = fullTextEm.getSearchFactory() .buildQueryBuilder() .forEntity( IndexedNews.class ) .get(); Query luceneQuery = queryBuilder.keyword().wildcard().onField( "newsId" ).ignoreFieldBridge().matching( "tit*" ).createQuery(); @SuppressWarnings("unchecked") List<IndexedNews> list = fullTextEm.createFullTextQuery( luceneQuery ).getResultList(); assertThat( list ).hasSize( 1 ); List<IndexedLabel> labels = list.get( 0 ).getLabels(); assertThat( labels ).hasSize( 2 ); assertThat( contains( labels, "massindex" ) ).isTrue(); assertThat( contains( labels, "test" ) ).isTrue(); fullTextEm.getTransaction().commit(); fullTextEm.close(); } @SuppressWarnings("unchecked") private void assertAssociatedElementsHaveBeenIndexed() throws Exception { FullTextEntityManager fullTextEm = Search.getFullTextEntityManager( createEntityManager() ); fullTextEm.getTransaction().begin(); QueryBuilder b = fullTextEm.getSearchFactory().buildQueryBuilder().forEntity( IndexedLabel.class ).get(); { Query luceneQuery = b.keyword().wildcard().onField( "name" ).matching( "tes*" ).createQuery(); List<IndexedLabel> labels = fullTextEm.createFullTextQuery( luceneQuery ).getResultList(); assertThat( labels ).hasSize( 1 ); assertThat( contains( labels, "test" ) ).isTrue(); } { Query luceneQuery = b.keyword().wildcard().onField( "name" ).matching( "mas*" ).createQuery(); List<IndexedLabel> labels = fullTextEm.createFullTextQuery( luceneQuery ).getResultList(); assertThat( labels ).hasSize( 1 ); assertThat( contains( labels, "massindex" ) ).isTrue(); } fullTextEm.getTransaction().commit(); fullTextEm.close(); } private boolean contains(List<IndexedLabel> list, String label) { for ( IndexedLabel indexedLabel : list ) { if ( indexedLabel.getName().equals( label ) ) { return true; } } return false; } private EntityManager createEntityManager() { return getFactory().createEntityManager(); } private void startAndWaitMassIndexing(Class<?>... entityTypes) throws InterruptedException { FullTextEntityManager fullTextEm = Search.getFullTextEntityManager( createEntityManager() ); fullTextEm.createIndexer( entityTypes ).purgeAllOnStart( true ).startAndWait(); int numDocs = fullTextEm.getSearchFactory().getIndexReaderAccessor().open( entityTypes ).numDocs(); fullTextEm.close(); assertThat( numDocs ).isGreaterThan( 0 ); } private void purgeAll(Class<?>... entityTypes) throws Exception { FullTextEntityManager fullTextEm = Search.getFullTextEntityManager( createEntityManager() ); for ( Class<?> entityType : entityTypes ) { fullTextEm.purgeAll( entityType ); fullTextEm.flushToIndexes(); } int numDocs = fullTextEm.getSearchFactory().getIndexReaderAccessor().open( entityTypes ).numDocs(); fullTextEm.close(); assertThat( numDocs ).isEqualTo( 0 ); } @Override public Class<?>[] getAnnotatedClasses() { return new Class<?>[] { IndexedNews.class, IndexedLabel.class }; } @Override protected void configure(GetterPersistenceUnitInfo info) { super.configure( info ); info.getProperties().setProperty( "hibernate.search.default.directory_provider", "ram" ); // Infinispan requires to be set to distribution mode for this test to pass info.getProperties().setProperty( "hibernate.ogm.infinispan.configuration_resourcename", "infinispan-dist.xml" ); } }