[hibernate-commits] Hibernate SVN: r19022 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/query/dsl/v2/impl and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Mar 18 14:58:28 EDT 2010


Author: epbernard
Date: 2010-03-18 14:58:27 -0400 (Thu, 18 Mar 2010)
New Revision: 19022

Added:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java
Modified:
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java
   search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
   search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java
Log:
HSEARCH-414 add boolean query framework (needs test) and common query methods (boostedTo etc)

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/BooleanJunction.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -0,0 +1,26 @@
+package org.hibernate.search.query.dsl.v2;
+
+import org.apache.lucene.search.Query;
+
+/**
+ * Represents a boolean query that can contains one or more elements to join
+ *
+ * @author Emmanuel Bernard
+ */
+public interface BooleanJunction<T extends BooleanJunction> extends QueryCustomization<T> {
+	/**
+	 * The boolean query results should match the subquery
+	 */
+	BooleanJunction should(Query query);
+
+	/**
+	 * The boolean query results must (or must not) match the subquery
+	 * Call the .not() method to ensure results of the boolean query do NOT match the subquery.
+	 */
+	MustJunction must(Query query);
+
+	/**
+	 * Return the lucene query representing the boolean operation
+	 */
+	Query createQuery();
+}

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/MustJunction.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -0,0 +1,14 @@
+package org.hibernate.search.query.dsl.v2;
+
+/**
+ * Represents the context in which a must clause is described.
+ *  
+ * @author Emmanuel Bernard
+ */
+public interface MustJunction extends BooleanJunction<MustJunction> {
+	/**
+	 * Negate the must clause.
+	 * Results of the boolean query do NOT match the subquery.
+	 */
+	BooleanJunction not();
+}

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java	2010-03-18 18:17:05 UTC (rev 19021)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryBuilder.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -8,4 +8,10 @@
 	 * build a term query
 	 */
 	TermContext term();
+
+
+	/**
+	 * Boolean query
+	 */
+	BooleanJunction<BooleanJunction> bool();
 }

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/QueryCustomization.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -0,0 +1,40 @@
+package org.hibernate.search.query.dsl.v2;
+
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.Query;
+
+/**
+ * Operations common to all types of queries
+ *
+ * @author Emmanuel Bernard
+ */
+public interface QueryCustomization<T> {
+
+	/**
+	 * Boost the query to a given value
+	 * Most of the time positive float:
+	 *  - lower than 1 to diminish the weight
+	 *  - higher than 1 to increase the weight
+	 *
+	 * Could be negative but not unless you understand what is going on (advanced)
+	 */
+	T boostedTo(float boost);
+
+	/**
+	 * All results matching the query have a constant score equals to the boost
+	 * FIXME is that true?
+	 */
+	T constantScore();
+
+	/**
+	 * Filter the query results with the Filter instance
+	 */
+	T filter(Filter filter);
+
+	//TODO filter(String) + parameters
+
+	/**
+	 * Create a Lucene query
+	 */
+	Query createQuery();
+}

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java	2010-03-18 18:17:05 UTC (rev 19021)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/TermCustomization.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -5,7 +5,7 @@
 /**
 * @author Emmanuel Bernard
 */
-public interface TermCustomization {
+public interface TermCustomization extends QueryCustomization<TermCustomization> {
 	/**
 	 * Advanced
 	 * Do not execute the analyzer on the text.
@@ -28,9 +28,4 @@
 	//TODO make it mutually exclusive with fuzzy use (but that's much more complex)
 	TermCustomization wildcard();
 
-	/**
-	 * Create a Lucene query
-	 */
-	Query createQuery();
-
 }

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/BooleanQueryBuilder.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -0,0 +1,87 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.query.dsl.v2.BooleanJunction;
+import org.hibernate.search.query.dsl.v2.MustJunction;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class BooleanQueryBuilder implements MustJunction {
+	private final List<BooleanClause> clauses;
+	private final QueryCustomizer queryCustomizer;
+
+	BooleanQueryBuilder() {
+		clauses = new ArrayList<BooleanClause>(5);
+		queryCustomizer = new QueryCustomizer();
+	}
+	
+	public BooleanJunction not() {
+		final int lastIndex = clauses.size() -1;
+		final BooleanClause last = clauses.get(lastIndex);
+		if ( ! last.getOccur().equals( BooleanClause.Occur.MUST ) ) {
+			throw new AssertionFailure( "Cannot negate class: " + last.getOccur() );
+		}
+		clauses.add( lastIndex, new BooleanClause( last.getQuery(), BooleanClause.Occur.MUST_NOT ) );
+		return this;
+	}
+
+	public BooleanJunction should(Query query) {
+		clauses.add( new BooleanClause( query, BooleanClause.Occur.SHOULD ) );
+		return this;
+	}
+
+	public MustJunction must(Query query) {
+		clauses.add( new BooleanClause( query, BooleanClause.Occur.SHOULD ) );
+		return this;
+	}
+
+	public MustJunction boostedTo(float boost) {
+		queryCustomizer.boostedTo( boost );
+		return this;
+	}
+
+	public MustJunction constantScore() {
+		queryCustomizer.constantScore();
+		return this;
+	}
+
+	public MustJunction filter(Filter filter) {
+		queryCustomizer.filter(filter);
+		return this;
+	}
+
+	public Query createQuery() {
+		final int nbrOfClauses = clauses.size();
+		if ( nbrOfClauses == 0) {
+			throw new AssertionFailure( "Cannot create an empty boolean query" );
+		}
+		else if ( nbrOfClauses == 1 ) {
+			final BooleanClause uniqueClause = clauses.get( 0 );
+			if ( uniqueClause.getOccur().equals( BooleanClause.Occur.MUST_NOT ) ) {
+				//FIXME We have two choices here, raise an exception or combine with an All query. #2 is done atm.
+				//TODO which normfield to use and how to pass it?
+				should( new MatchAllDocsQuery() );
+			}
+			else {
+				//optimize
+				return queryCustomizer.setWrappedQuery( uniqueClause.getQuery() ).createQuery();
+			}
+		}
+
+		BooleanQuery query = new BooleanQuery( );
+		for (BooleanClause clause : clauses) {
+			query.add( clause );
+		}
+		return queryCustomizer.setWrappedQuery( query ).createQuery();
+	}
+}

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java	2010-03-18 18:17:05 UTC (rev 19021)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedQueryBuilder.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -3,6 +3,7 @@
 import org.apache.lucene.analysis.Analyzer;
 
 import org.hibernate.search.SearchFactory;
+import org.hibernate.search.query.dsl.v2.BooleanJunction;
 import org.hibernate.search.query.dsl.v2.QueryBuilder;
 import org.hibernate.search.query.dsl.v2.TermContext;
 
@@ -23,4 +24,8 @@
 	public TermContext term() {
 		return new ConnectedTermContext( queryAnalyzer, factory);
 	}
+
+	public BooleanJunction bool() {
+		return new BooleanQueryBuilder();
+	}
 }

Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java	2010-03-18 18:17:05 UTC (rev 19021)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/ConnectedTermContext.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -12,6 +12,7 @@
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.FuzzyQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
@@ -28,7 +29,7 @@
 /**
  * @author Emmanuel Bernard
  */
-public class ConnectedTermContext implements TermContext {
+class ConnectedTermContext implements TermContext {
 	private final SearchFactory factory;
 	private final Analyzer queryAnalyzer;
 
@@ -62,6 +63,7 @@
 		private final String field;
 		private final String text;
 		private final Analyzer queryAnalyzer;
+		private final QueryCustomizer queryCustomizer;
 
 		private boolean ignoreAnalyzer;
 		private Approximation approximation = Approximation.EXACT;
@@ -73,6 +75,7 @@
 			this.field = field;
 			this.text = text;
 			this.queryAnalyzer = queryAnalyzer;
+			this.queryCustomizer = new QueryCustomizer();
 		}
 
 		public TermCustomization ignoreAnalyzer() {
@@ -96,9 +99,25 @@
 			return this;
 		}
 
+		public TermCustomization boostedTo(float boost) {
+			queryCustomizer.boostedTo( boost );
+			return this;
+		}
+
+		public TermCustomization constantScore() {
+			queryCustomizer.constantScore();
+			return this;
+		}
+
+		public TermCustomization filter(Filter filter) {
+			queryCustomizer.filter( filter );
+			return this;
+		}
+
 		public Query createQuery() {
+			final Query result;
 			if ( ignoreAnalyzer ) {
-				return createTermQuery( text );	
+				result = createTermQuery( text );
 			}
 			else {
 				List<String> terms;
@@ -112,18 +131,19 @@
 					throw new SearchException("try to search with an empty string: " + field);
 				}
 				else if (terms.size() == 1 ) {
-					return createTermQuery( terms.get( 0 ) );
+					result = createTermQuery( terms.get( 0 ) );
 				}
 				else {
-					BooleanQuery finalQuery = new BooleanQuery();
+					BooleanQuery booleanQuery = new BooleanQuery();
 					for (String term : terms) {
 						Query termQuery = createTermQuery(term);
 						//termQuery.setBoost( boost );
-						finalQuery.add( termQuery, BooleanClause.Occur.SHOULD );
+						booleanQuery.add( termQuery, BooleanClause.Occur.SHOULD );
 					}
-					return finalQuery;
+					result = booleanQuery;
 				}
 			}
+			return queryCustomizer.setWrappedQuery( result ).createQuery();
 		}
 
 		private Query createTermQuery(String term) {
@@ -146,19 +166,26 @@
 		}
 
 		private List<String> getAllTermsFromText(String fieldName, String text, Analyzer analyzer) throws IOException {
-			Reader reader = new StringReader(text);
-			TokenStream stream = analyzer.reusableTokenStream( fieldName, reader);
-			TermAttribute attribute = (TermAttribute) stream.addAttribute( TermAttribute.class );
-			stream.reset();
+			//it's better not to apply the analyzer with windcards as * and ? can be mistakenly removed
 			List<String> terms = new ArrayList<String>();
-			while ( stream.incrementToken() ) {
-				if ( attribute.termLength() > 0 ) {
-					String term = attribute.term();
-					terms.add( term );
+			if ( approximation == Approximation.WILDCARD ) {
+				terms.add( text );
+			}
+			else {
+				Reader reader = new StringReader(text);
+				TokenStream stream = analyzer.reusableTokenStream( fieldName, reader);
+				TermAttribute attribute = (TermAttribute) stream.addAttribute( TermAttribute.class );
+				stream.reset();
+
+				while ( stream.incrementToken() ) {
+					if ( attribute.termLength() > 0 ) {
+						String term = attribute.term();
+						terms.add( term );
+					}
 				}
+				stream.end();
+				stream.close();
 			}
-			stream.end();
-    		stream.close();
 			return terms;
 		}
 

Added: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java	                        (rev 0)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/dsl/v2/impl/QueryCustomizer.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -0,0 +1,56 @@
+package org.hibernate.search.query.dsl.v2.impl;
+
+import org.apache.lucene.search.ConstantScoreQuery;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.FilteredQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryFilter;
+import org.apache.lucene.search.QueryWrapperFilter;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.query.dsl.v2.QueryCustomization;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class QueryCustomizer implements QueryCustomization<QueryCustomizer> {
+	private float boost = 1f;
+	private boolean constantScore;
+	private Query wrappedQuery;
+	private Filter filter;
+
+	public QueryCustomizer boostedTo(float boost) {
+		this.boost = boost;
+		return this;
+	}
+
+	public QueryCustomizer constantScore() {
+		constantScore = true;
+		return this;
+	}
+
+	public QueryCustomizer filter(Filter filter) {
+		this.filter = filter;
+		return this;
+	}
+
+	public QueryCustomizer setWrappedQuery(Query wrappedQuery) {
+		this.wrappedQuery = wrappedQuery;
+		return this;
+	}
+
+	public Query createQuery() {
+		Query finalQuery = wrappedQuery;
+		if (wrappedQuery == null) {
+			throw new AssertionFailure( "wrapped query not set" );
+		}
+		finalQuery.setBoost( boost );
+		if (filter != null) {
+			finalQuery = new FilteredQuery(finalQuery, filter);
+		}
+		if ( constantScore ) {
+			finalQuery = new ConstantScoreQuery( new QueryWrapperFilter( finalQuery ) );
+		}
+		return finalQuery;
+	}
+}

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java	2010-03-18 18:17:05 UTC (rev 19021)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/DSLTest.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -14,6 +14,7 @@
 import org.hibernate.Transaction;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.search.Environment;
+import org.hibernate.search.FullTextQuery;
 import org.hibernate.search.FullTextSession;
 import org.hibernate.search.Search;
 import org.hibernate.search.annotations.Factory;
@@ -27,16 +28,9 @@
 public class DSLTest extends SearchTestCase {
 
 	public void testTermQueryOnAnalyzer() throws Exception {
-		Session session = openSession();
-		FullTextSession fts = Search.getFullTextSession( session );
+		FullTextSession fts = initData();
+
 		Transaction transaction = fts.beginTransaction();
-		fts.persist( new Month("January", "Month of colder and whitening") );
-		fts.persist( new Month("February", "Month of snowboarding") );
-		transaction.commit();
-
-		fts.clear();
-
-		transaction = fts.beginTransaction();
 		final QueryBuilder monthQb = fts.getSearchFactory()
 				.buildQueryBuilder().forEntity( Month.class ).get();
 		Query 
@@ -67,27 +61,15 @@
 
 		query = monthQb.term().on( "mythology" ).matches( "Month" ).createQuery();
 
-		final List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
-		assertEquals( 2, results.size() );
+		transaction.commit();
 
-		for (Month entity : results) {
-			fts.delete( entity );
-		}
-		transaction.commit();
-		fts.close();
+		cleanData( fts );
 	}
 
-	public void tesFuzzyAndWildcardQuery() throws Exception {
-		Session session = openSession();
-		FullTextSession fts = Search.getFullTextSession( session );
+	public void testFuzzyAndWildcardQuery() throws Exception {
+		FullTextSession fts = initData();
+
 		Transaction transaction = fts.beginTransaction();
-		fts.persist( new Month("January", "Month of colder and whitening") );
-		fts.persist( new Month("February", "Month of snowboarding") );
-		transaction.commit();
-
-		fts.clear();
-
-		transaction = fts.beginTransaction();
 		final QueryBuilder monthQb = fts.getSearchFactory()
 				.buildQueryBuilder().forEntity( Month.class ).get();
 		Query
@@ -106,19 +88,72 @@
 				.term().on( "mythology" ).matches( "mon*" )
 					.wildcard()
 				.createQuery();
-
+		System.out.println(query.toString(  ));
 		assertEquals( 2, fts.createFullTextQuery( query, Month.class ).getResultSize() );
 
-		final List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
+		transaction.commit();
+
+		cleanData( fts );
+	}
+
+	public void testQueryCustomization() throws Exception {
+		FullTextSession fts = initData();
+
+		Transaction transaction = fts.beginTransaction();
+		final QueryBuilder monthQb = fts.getSearchFactory()
+				.buildQueryBuilder().forEntity( Month.class ).get();
+		Query
+
+		//combined query, January and february both contain whitening but February in a longer text
+		query = monthQb
+				.bool()
+					.should( monthQb.term().on( "mythology" ).matches( "whitening" ).createQuery() )
+					.should( monthQb.term().on( "history" ).matches( "whitening" ).createQuery() )
+				.createQuery();
+
+		List<Month> results = fts.createFullTextQuery( query, Month.class ).list();
 		assertEquals( 2, results.size() );
+		assertEquals( "January", results.get( 0 ).getName() );
 
+		//boosted query, January and february both contain whitening but February in a longer text
+		//since history is boosted, February should come first though
+		query = monthQb
+				.bool()
+					.should( monthQb.term().on( "mythology" ).matches( "whitening" ).createQuery() )
+					.should( monthQb.term().on( "history" ).matches( "whitening" ).boostedTo( 30 ).createQuery() )
+				.createQuery();
+
+		results = fts.createFullTextQuery( query, Month.class ).list();
+		assertEquals( 2, results.size() );
+		assertEquals( "February", results.get( 0 ).getName() );
+
+		transaction.commit();
+
+		cleanData( fts );
+	}
+
+	private void cleanData(FullTextSession fts) {
+		Transaction tx = fts.beginTransaction();
+		final List<Month> results = fts.createQuery( "from " + Month.class.getName() ).list();
+		assertEquals( 2, results.size() );
+
 		for (Month entity : results) {
 			fts.delete( entity );
 		}
-		transaction.commit();
+		tx.commit();
 		fts.close();
 	}
 
+	private FullTextSession initData() {
+		Session session = openSession();
+		FullTextSession fts = Search.getFullTextSession( session );
+		Transaction tx = fts.beginTransaction();
+		fts.persist( new Month("January", "Month of colder and whitening", "Historically colder than any other month in the northern hemisphere") );
+		fts.persist( new Month("February", "Month of snowboarding", "Historically, the month where we make babies while watching the whitening landscape") );
+		tx.commit();
+		fts.clear();
+		return fts;
+	}
 
 	@Override
 	protected Class<?>[] getMappings() {

Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java	2010-03-18 18:17:05 UTC (rev 19021)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/query/dsl/Month.java	2010-03-18 18:58:27 UTC (rev 19022)
@@ -17,9 +17,10 @@
 public class Month {
 	public Month() {}
 	
-	public Month(String name, String mythology) {
+	public Month(String name, String mythology, String history) {
 		this.name = name;
 		this.mythology = mythology;
+		this.history = history;
 	}
 
 	@Id @GeneratedValue
@@ -40,5 +41,11 @@
 	public String getMythology() { return mythology; }
 	public void setMythology(String mythology) { this.mythology = mythology; }
 	private String mythology;
+
+	@Field
+	public String getHistory() { return history; }
+	public void setHistory(String history) { this.history = history; }
+	private String history;
+
 }
 



More information about the hibernate-commits mailing list