/*
* 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;
}
}