/* * 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.query.initandlookup; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.apache.lucene.search.MatchAllDocsQuery; import org.hibernate.Transaction; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.exception.SearchException; import org.hibernate.search.test.util.FullTextSessionBuilder; import org.hibernate.search.testsupport.BytemanHelper; import org.hibernate.search.testsupport.TestForIssue; import org.hibernate.search.testsupport.BytemanHelper.BytemanAccessor; import org.hibernate.search.testsupport.junit.ElasticsearchSupportInProgress; import org.jboss.byteman.contrib.bmunit.BMRule; import org.jboss.byteman.contrib.bmunit.BMUnitRunner; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; /** * A bunch of indirect tests to verify that object lookup method and database retrieval method are configurable. * Assertions are via Byteman determining that the appropriate object initializer was used. * * @author Hardy Ferentschik * @author Sanne Grinovero */ @TestForIssue(jiraKey = "HSEARCH-1119") @RunWith(BMUnitRunner.class) @Category(ElasticsearchSupportInProgress.class) // HSEARCH-2481 Byteman-based tests re-executed in the Elasticsearch module won't work public class ObjectLookupAndDatabaseRetrievalConfigurationTest { @Rule public BytemanAccessor byteman = BytemanHelper.createAccessor(); @Test @BMRule(targetClass = "org.hibernate.search.query.hibernate.impl.CriteriaObjectInitializer", targetMethod = "initializeObjects(java.util.List, java.util.LinkedHashMap, org.hibernate.search.query.hibernate.impl.ObjectInitializationContext)", helper = "org.hibernate.search.testsupport.BytemanHelper", action = "countInvocation()", name = "testSetLookupMethodPersistenceContext") public void testDefaultLookupMethod() throws Exception { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( null, null ) ) { indexTestData( builder ); FullTextSession fullTextSession = builder.openFullTextSession(); Transaction tx = fullTextSession.beginTransaction(); FullTextQuery query = fullTextSession.createFullTextQuery( new MatchAllDocsQuery() ); query.list(); tx.commit(); fullTextSession.close(); Assert.assertEquals( "CriteriaObjectInitializer should have been used as object initializer", 1, byteman.getAndResetInvocationCount() ); } } @Test @BMRule(targetClass = "org.hibernate.search.query.hibernate.impl.PersistenceContextObjectInitializer", targetMethod = "initializeObjects(java.util.List, java.util.LinkedHashMap, org.hibernate.search.query.hibernate.impl.ObjectInitializationContext)", helper = "org.hibernate.search.testsupport.BytemanHelper", action = "countInvocation()", name = "testSetLookupMethodPersistenceContext") public void testSetLookupMethodPersistenceContextUpperCase() throws Exception { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( "PERSISTENCE_CONTEXT", null ) ) { indexTestData( builder ); FullTextSession fullTextSession = builder.openFullTextSession(); Transaction tx = fullTextSession.beginTransaction(); FullTextQuery query = fullTextSession.createFullTextQuery( new MatchAllDocsQuery() ); query.list(); tx.commit(); fullTextSession.close(); Assert.assertEquals( "PersistenceContextObjectInitializer should have been used as object initializer", 1, byteman.getAndResetInvocationCount() ); } } @Test @BMRule(targetClass = "org.hibernate.search.query.hibernate.impl.PersistenceContextObjectInitializer", targetMethod = "initializeObjects(java.util.List, java.util.LinkedHashMap, org.hibernate.search.query.hibernate.impl.ObjectInitializationContext)", helper = "org.hibernate.search.testsupport.BytemanHelper", action = "countInvocation()", name = "testSetLookupMethodPersistenceContext") public void testSetLookupMethodPersistenceContextLowerCase() throws Exception { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( "persistence_context", null ) ) { indexTestData( builder ); FullTextSession fullTextSession = builder.openFullTextSession(); Transaction tx = fullTextSession.beginTransaction(); FullTextQuery query = fullTextSession.createFullTextQuery( new MatchAllDocsQuery() ); query.list(); tx.commit(); fullTextSession.close(); Assert.assertEquals( "PersistenceContextObjectInitializer should have been used as object initializer", 1, byteman.getAndResetInvocationCount() ); } } @Test @BMRule(targetClass = "org.hibernate.search.query.hibernate.impl.LookupObjectInitializer", targetMethod = "initializeObjects(java.util.List, java.util.LinkedHashMap, org.hibernate.search.query.hibernate.impl.ObjectInitializationContext)", helper = "org.hibernate.search.testsupport.BytemanHelper", action = "countInvocation()", name = "testSetLookupMethodPersistenceContext") public void testSetDatabaseRetrievalMethodUpperCase() throws Exception { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( null, "FIND_BY_ID" ) ) { indexTestData( builder ); FullTextSession fullTextSession = builder.openFullTextSession(); Transaction tx = fullTextSession.beginTransaction(); FullTextQuery query = fullTextSession.createFullTextQuery( new MatchAllDocsQuery() ); query.list(); tx.commit(); fullTextSession.close(); Assert.assertEquals( "LookupObjectInitializer should have been used as object initializer", 1, byteman.getAndResetInvocationCount() ); } } @Test @BMRule(targetClass = "org.hibernate.search.query.hibernate.impl.LookupObjectInitializer", targetMethod = "initializeObjects(java.util.List, java.util.LinkedHashMap, org.hibernate.search.query.hibernate.impl.ObjectInitializationContext)", helper = "org.hibernate.search.testsupport.BytemanHelper", action = "countInvocation()", name = "testSetLookupMethodPersistenceContext") public void testSetDatabaseRetrievalMethodLoweCase() throws Exception { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( null, "find_by_id" ) ) { indexTestData( builder ); FullTextSession fullTextSession = builder.openFullTextSession(); Transaction tx = fullTextSession.beginTransaction(); FullTextQuery query = fullTextSession.createFullTextQuery( new MatchAllDocsQuery() ); query.list(); tx.commit(); fullTextSession.close(); Assert.assertEquals( "LookupObjectInitializer should have been used as object initializer", 1, byteman.getAndResetInvocationCount() ); } } @Test public void testSetInvalidLookupMethodThrowsException() throws Exception { try { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( "foo", null ) ) { fail( "The setup of the search factory should have failed due to invalid value." ); } } catch (SearchException e) { assertTrue( "Unexpected error message: " + e.getMessage(), e.getMessage().startsWith( "HSEARCH000217" ) ); } } @Test public void testSetInvalidRetrievalMethodThrowsException() throws Exception { try { try ( FullTextSessionBuilder builder = buildFullTextSessionBuilder( null, "foo" ) ) { fail( "The setup of the search factory should have failed due to invalid value." ); } } catch (SearchException e) { assertTrue( "Unexpected error message: " + e.getMessage(), e.getMessage().startsWith( "HSEARCH000217" ) ); } } private FullTextSessionBuilder buildFullTextSessionBuilder(String objectLookUpMethod, String databaseRetrievalMethod) { FullTextSessionBuilder fullTextSessionBuilder = new FullTextSessionBuilder() .addAnnotatedClass( Foo.class ); if ( objectLookUpMethod != null ) { fullTextSessionBuilder.setProperty( "hibernate.search.query.object_lookup_method", objectLookUpMethod ); } if ( databaseRetrievalMethod != null ) { fullTextSessionBuilder.setProperty( "hibernate.search.query.database_retrieval_method", databaseRetrievalMethod ); } return fullTextSessionBuilder.build(); } private void indexTestData(FullTextSessionBuilder builder) { FullTextSession session = builder.openFullTextSession(); Transaction transaction = session.beginTransaction(); // need to index at least two instances. In the single instance case a search will not go via the object initializer Foo foo = new Foo(); session.persist( foo ); Foo snafu = new Foo(); session.persist( snafu ); transaction.commit(); session.close(); } @Indexed @Entity public static class Foo { @Id @GeneratedValue int id; } }