package org.hibernate.search.test.sorting;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
import org.hibernate.search.backend.spi.Work;
import org.hibernate.search.backend.spi.WorkType;
import org.hibernate.search.backend.spi.Worker;
import org.hibernate.search.query.engine.spi.HSQuery;
import org.hibernate.search.testsupport.junit.SearchFactoryHolder;
import org.hibernate.search.testsupport.setup.TransactionContextForTest;
import org.junit.Rule;
import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
/**
* @author gustavonalle
*/
public class SortingNullableTest {
@Rule
public SearchFactoryHolder factoryHolder = new SearchFactoryHolder(Person.class);
@Test
public void testSortOnNullableNumericField() throws Exception {
storeObjects(
new Person(1, 25, "name1"),
new Person(2, 22, null),
new Person(3, null, "name3")
);
HSQuery nameQuery = queryForValueNullAndSorting("name", SortField.Type.STRING);
assertEquals(nameQuery.queryEntityInfos().size(), 1);
HSQuery ageQuery = queryForValueNullAndSorting("age", SortField.Type.INT);
assertEquals(ageQuery.queryEntityInfos().size(), 1);
}
private HSQuery queryForValueNullAndSorting(String fieldName, SortField.Type sortType) {
Query query = factoryHolder.getSearchFactory().
buildQueryBuilder().forEntity(Person.class).get().keyword().onField(fieldName).matching(null).createQuery();
HSQuery hsQuery = factoryHolder.getSearchFactory().createHSQuery().luceneQuery(query);
Sort sort = new Sort(new SortField(fieldName, sortType));
hsQuery.targetedEntities(Arrays.<Class<?>>asList(Person.class)).sort(sort);
return hsQuery;
}
private void storeObjects(Person... persons) {
Worker worker = factoryHolder.getSearchFactory().getWorker();
TransactionContextForTest tc = new TransactionContextForTest();
for (Person person : persons) {
Work work = new Work(person, person.id, WorkType.UPDATE, false);
worker.performWork(work, tc);
}
tc.end();
}
@Indexed
private class Person {
@DocumentId
final int id;
@Field(store = Store.YES, analyze = Analyze.NO, indexNullAs = Field.DEFAULT_NULL_TOKEN)
final Integer age;
@Field(store = Store.YES, analyze = Analyze.NO, indexNullAs = Field.DEFAULT_NULL_TOKEN)
final String name;
Person(int id, Integer age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
}
}