/* * 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.engine; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.search.FullTextSession; import org.hibernate.search.Search; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.NumericField; import org.hibernate.search.annotations.Store; import org.hibernate.search.engine.ProjectionConstants; import org.hibernate.search.query.dsl.QueryContextBuilder; import org.hibernate.search.test.SearchTestBase; import org.hibernate.search.testsupport.TestForIssue; import org.hibernate.search.testsupport.junit.SkipOnElasticsearch; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertEquals; @Category(SkipOnElasticsearch.class) // This test is Lucene-specific. The generic equivalent is NumericFieldTest. public class LuceneNumericFieldTest extends SearchTestBase { @Override @Before public void setUp() throws Exception { super.setUp(); prepareData(); } @Override @After public void tearDown() throws Exception { cleanData(); super.tearDown(); } @Test @TestForIssue(jiraKey = "HSEARCH-1987") public void testOneOfSeveralFieldsIsNumeric() { try ( Session session = openSession() ) { FullTextSession fullTextSession = Search.getFullTextSession( session ); Transaction tx = fullTextSession.beginTransaction(); QueryContextBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder(); Query query = queryBuilder.forEntity( TouristAttraction.class ).get().all().createQuery(); @SuppressWarnings("unchecked") List<Object[]> list = fullTextSession.createFullTextQuery( query, TouristAttraction.class ) .setProjection( ProjectionConstants.DOCUMENT ) .list(); assertEquals( 1, list.size() ); Document document = (Document) list.iterator().next()[0]; IndexableField scoreNumeric = document.getField( "scoreNumeric" ); assertThat( scoreNumeric.numericValue() ).isEqualTo( 23 ); IndexableField scoreString = document.getField( "scoreString" ); assertThat( scoreString.numericValue() ).isNull(); assertThat( scoreString.stringValue() ).isEqualTo( "23" ); tx.commit(); } } @Test @TestForIssue(jiraKey = "HSEARCH-1987") public void testNumericMappingOfEmbeddedFields() { try ( Session session = openSession() ) { FullTextSession fullTextSession = Search.getFullTextSession( session ); Transaction tx = fullTextSession.beginTransaction(); QueryContextBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder(); Query query = queryBuilder.forEntity( ScoreBoard.class ).get().all().createQuery(); @SuppressWarnings("unchecked") List<Object[]> list = fullTextSession.createFullTextQuery( query, ScoreBoard.class ) .setProjection( ProjectionConstants.DOCUMENT ) .list(); assertEquals( 1, list.size() ); Document document = (Document) list.iterator().next()[0]; IndexableField scoreNumeric = document.getField( "score_id" ); assertThat( scoreNumeric.numericValue() ).isEqualTo( 1 ); IndexableField beta = document.getField( "score_beta" ); assertThat( beta.numericValue() ).isEqualTo( 100 ); tx.commit(); } } @Override public Class<?>[] getAnnotatedClasses() { return new Class<?>[]{ TouristAttraction.class, ScoreBoard.class, Score.class }; } private void prepareData() { try ( Session session = openSession() ) { FullTextSession fullTextSession = Search.getFullTextSession( session ); Transaction tx = fullTextSession.beginTransaction(); TouristAttraction attraction = new TouristAttraction( 1, (short) 23, (short) 46L ); fullTextSession.save( attraction ); Score score1 = new Score(); score1.id = 1; score1.subscore = 100; fullTextSession.save( score1 ); ScoreBoard scoreboard = new ScoreBoard(); scoreboard.id = 1l; scoreboard.scores.add( score1 ); fullTextSession.save( scoreboard ); tx.commit(); } } @SuppressWarnings("unchecked") private void cleanData() { try ( Session session = openSession() ) { FullTextSession fullTextSession = Search.getFullTextSession( session ); Transaction tx = fullTextSession.beginTransaction(); List<TouristAttraction> attractions = fullTextSession.createCriteria( TouristAttraction.class ).list(); for ( TouristAttraction attraction : attractions ) { fullTextSession.delete( attraction ); } List<ScoreBoard> scoreboards = fullTextSession.createCriteria( ScoreBoard.class ).list(); for ( ScoreBoard scoreboard : scoreboards ) { fullTextSession.delete( scoreboard ); } List<Score> scores = fullTextSession.createCriteria( Score.class ).list(); for ( Score score : scores ) { fullTextSession.delete( score ); } tx.commit(); } } @Indexed @Entity static class ScoreBoard { @Id Long id; @IndexedEmbedded(includeEmbeddedObjectId = true, prefix = "score_") @OneToMany Set<Score> scores = new HashSet<Score>(); } @Indexed @Entity static class Score { @Id @NumericField Integer id; @Field(name = "beta", store = Store.YES) Integer subscore; } }