/* * 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.dsl; import java.util.List; import org.apache.lucene.search.NumericRangeQuery; import org.apache.lucene.search.Query; import org.hibernate.search.annotations.DocumentId; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.backend.spi.Work; import org.hibernate.search.backend.spi.WorkType; import org.hibernate.search.query.dsl.QueryBuilder; import org.hibernate.search.query.engine.spi.EntityInfo; import org.hibernate.search.testsupport.TestForIssue; import org.hibernate.search.testsupport.junit.SearchFactoryHolder; import org.hibernate.search.testsupport.setup.TransactionContextForTest; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; /** * A query targeting a numeric-encoded property needs to be a NumericQuery even if it's using 'indexNullAs' markers. * * @author Sanne Grinovero (C) 2015 Red Hat Inc. */ @TestForIssue(jiraKey = "HSEARCH-1973") public class NumericTypeWithNullEncodingTest { @Rule public SearchFactoryHolder sfHolder = new SearchFactoryHolder( SomeEntity.class ) .withProperty( org.hibernate.search.cfg.Environment.DEFAULT_NULL_TOKEN, "-7" ); @Before public void prepareTestData() { storeData( "title-one", 1, 1 ); storeData( "title-two", 2, null ); storeData( "title-three", 3, 3 ); } @Test public void verifyExplicitRangeQuery() { Query query = getQueryBuilder() .range() .onField( "age" ) .from( 1 ).excludeLimit() .to( 3 ).excludeLimit() .createQuery(); Assert.assertTrue( query instanceof NumericRangeQuery ); List<EntityInfo> queryEntityInfos = runProjection( query, "title" ); Assert.assertEquals( 1, queryEntityInfos.size() ); EntityInfo entityInfo = queryEntityInfos.get( 0 ); Assert.assertEquals( "title-two", entityInfo.getProjection()[0] ); } @Test public void verifyExplicitKeywordQuery() { Query query = getQueryBuilder() .keyword() .onField( "age" ) .matching( 2 ) .createQuery(); Assert.assertTrue( query instanceof NumericRangeQuery ); List<EntityInfo> queryEntityInfos = runProjection( query, "title" ); Assert.assertEquals( 1, queryEntityInfos.size() ); EntityInfo entityInfo = queryEntityInfos.get( 0 ); Assert.assertEquals( "title-two", entityInfo.getProjection()[0] ); } @Test public void verifyCustomNullEncoding() { Query query = getQueryBuilder() .keyword() .onField( "nullableAge" ) .matching( null ) .createQuery(); Assert.assertTrue( query instanceof NumericRangeQuery ); Assert.assertEquals( "[-1 TO -1]", query.toString( "nullableAge" ) ); List<EntityInfo> queryEntityInfos = runProjection( query, "title" ); Assert.assertEquals( 1, queryEntityInfos.size() ); EntityInfo entityInfo = queryEntityInfos.get( 0 ); Assert.assertEquals( "title-two", entityInfo.getProjection()[0] ); } @Test public void verifyNullEncoding() { Query query = getQueryBuilder() .keyword() .onField( "age" ) .matching( null ) .createQuery(); Assert.assertTrue( query instanceof NumericRangeQuery ); Assert.assertEquals( "[-7 TO -7]", query.toString( "age" ) ); List<EntityInfo> queryEntityInfos = runProjection( query, "title" ); Assert.assertEquals( 0, queryEntityInfos.size() ); } private List<EntityInfo> runProjection(Query query, String fieldName) { return sfHolder .getSearchFactory() .createHSQuery( query, SomeEntity.class ) .projection( fieldName ) .queryEntityInfos(); } private QueryBuilder getQueryBuilder() { return sfHolder .getSearchFactory() .buildQueryBuilder() .forEntity( SomeEntity.class ) .get(); } private void storeData(String title, int value, Integer nullableAge) { SomeEntity entry = new SomeEntity(); entry.title = title; entry.age = value; entry.nullableAge = nullableAge; Work work = new Work( entry, entry.title, WorkType.ADD, false ); TransactionContextForTest tc = new TransactionContextForTest(); sfHolder.getSearchFactory().getWorker().performWork( work, tc ); tc.end(); } @Indexed public static class SomeEntity { @DocumentId String title; @Field(indexNullAs = Field.DEFAULT_NULL_TOKEN) int age; @Field(indexNullAs = "-1") Integer nullableAge; } }