[hibernate-commits] Hibernate SVN: r11420 - in trunk/HibernateExt/search/src: test/org/hibernate/search/test/embedded and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Apr 20 15:04:07 EDT 2007


Author: epbernard
Date: 2007-04-20 15:04:07 -0400 (Fri, 20 Apr 2007)
New Revision: 11420

Added:
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Author.java
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Order.java
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Product.java
Modified:
   trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java
   trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java
Log:
HSEARCH-40 support for @IndexedEmbedded collections

Modified: trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java
===================================================================
--- trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java	2007-04-19 09:08:44 UTC (rev 11419)
+++ trunk/HibernateExt/search/src/java/org/hibernate/search/engine/DocumentBuilder.java	2007-04-20 19:04:07 UTC (rev 11420)
@@ -89,7 +89,7 @@
 		//processedClasses.remove( clazz ); for the sake of completness
 
 		if ( idKeywordName == null ) {
-			throw new SearchException( "No document id for: " + clazz.getName() );
+			throw new SearchException( "No document id in: " + clazz.getName() );
 		}
 	}
 
@@ -189,17 +189,18 @@
 			maxLevel = embeddedAnn.depth() + level > maxLevel ? maxLevel : embeddedAnn.depth() + level;
 			level++;
 
+			XClass elementClass = member.getElementClass();
 			if ( maxLevel == Integer.MAX_VALUE //infinite
-					&& processedClasses.contains( member.getClassOrElementClass() ) ) {
+					&& processedClasses.contains( elementClass ) ) {
 				throw new SearchException(
 						"Circular reference. Duplicate use of "
-						+ member.getClassOrElementClass().getName()
+						+ elementClass.getName()
 						+ " in root entity " + beanClass.getName()
 						+ "#" + buildEmbeddedPrefix( prefix, embeddedAnn, member )
 				);
 			}
 			if (level <= maxLevel) {
-				processedClasses.add( member.getClassOrElementClass() ); //push
+				processedClasses.add( elementClass ); //push
 
 				setAccessible( member );
 				propertiesMetadata.embeddedGetters.add( member );
@@ -207,9 +208,27 @@
 				propertiesMetadata.embeddedPropertiesMetadata.add(metadata);
 				metadata.boost = getBoost( member );
 				String localPrefix = buildEmbeddedPrefix( prefix, embeddedAnn, member );
-				initializeMembers( member.getClassOrElementClass(), metadata, false, localPrefix, processedClasses);
+				initializeMembers( elementClass, metadata, false, localPrefix, processedClasses);
+				/**
+				 * We will only index the "expected" type but that's OK, HQL cannot do downcasting either
+				 */
+				if ( member.isArray() ) {
+					propertiesMetadata.embeddedContainers.add(PropertiesMetadata.Container.ARRAY);
+				}
+				else if ( member.isCollection() ) {
+					if ( Map.class.equals( member.getCollectionClass() ) ) {
+						//hum subclasses etc etc??
+						propertiesMetadata.embeddedContainers.add(PropertiesMetadata.Container.MAP);
+					}
+					else {
+						propertiesMetadata.embeddedContainers.add(PropertiesMetadata.Container.COLLECTION);
+					}
+				}
+				else {
+					propertiesMetadata.embeddedContainers.add(PropertiesMetadata.Container.OBJECT);
+				}
 
-				processedClasses.remove( member.getClassOrElementClass() ); //pop
+				processedClasses.remove( elementClass ); //pop
 			}
 			else if ( log.isTraceEnabled() ) {
 				String localPrefix = buildEmbeddedPrefix( prefix, embeddedAnn, member );
@@ -438,7 +457,33 @@
 			Object value = getMemberValue( instance, member );
 			//if ( ! Hibernate.isInitialized( value ) ) continue; //this sounds like a bad idea 
 			//TODO handle boost at embedded level: already stored in propertiesMedatada.boost
-			buildDocumentFields( value, doc, propertiesMetadata.embeddedPropertiesMetadata.get( i ) );
+
+			if (value == null) continue;
+
+			PropertiesMetadata embeddedMetadata = propertiesMetadata.embeddedPropertiesMetadata.get( i );
+			switch( propertiesMetadata.embeddedContainers.get(i) ) {
+				case ARRAY:
+					for ( Object arrayValue : (Object[]) value ) {
+						buildDocumentFields( arrayValue, doc, embeddedMetadata );
+					}
+					break;
+				case COLLECTION:
+					for ( Object collectionValue : (Collection) value ) {
+						buildDocumentFields( collectionValue, doc, embeddedMetadata );
+					}
+					break;
+				case MAP:
+					for ( Object collectionValue : ( (Map) value ).values() ) {
+						buildDocumentFields( collectionValue, doc, embeddedMetadata );
+					}
+					break;
+				case OBJECT:
+					buildDocumentFields( value, doc, embeddedMetadata );
+					break;
+				default:
+					throw new AssertionFailure("Unknown embedded container: "
+							+ propertiesMetadata.embeddedContainers.get(i) );
+			}
 		}
 	}
 
@@ -518,6 +563,14 @@
 		public final List<Field.Index> fieldIndex = new ArrayList<Field.Index>();
 		public final List<XMember> embeddedGetters = new ArrayList<XMember>();
 		public final List<PropertiesMetadata> embeddedPropertiesMetadata = new ArrayList<PropertiesMetadata>();
+		public final List<Container> embeddedContainers = new ArrayList<Container>();
 		public final List<XMember> containedInGetters = new ArrayList<XMember>();
+
+		public enum Container {
+			OBJECT,
+			COLLECTION,
+			MAP,
+			ARRAY
+		}
 	}
 }

Added: trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Author.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Author.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Author.java	2007-04-20 19:04:07 UTC (rev 11420)
@@ -0,0 +1,41 @@
+//$Id: $
+package org.hibernate.search.test.embedded;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.DocumentId;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class Author {
+	@Id
+	@GeneratedValue
+	@DocumentId
+	private Integer id;
+	@Field(index= Index.TOKENIZED)
+	private String name;
+
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}

Modified: trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java	2007-04-19 09:08:44 UTC (rev 11419)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/EmbeddedTest.java	2007-04-20 19:04:07 UTC (rev 11420)
@@ -9,8 +9,11 @@
 import org.hibernate.Session;
 import org.hibernate.Transaction;
 import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.queryParser.MultiFieldQueryParser;
 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.index.Term;
 
 /**
  * @author Emmanuel Bernard
@@ -136,10 +139,83 @@
 
 	}
 
+	public void testIndexedEmbeddedAndCollections() throws Exception {
+		Author a = new Author();
+		a.setName( "Voltaire" );
+		Author a2 = new Author();
+		a2.setName( "Victor Hugo" );
+		Author a3 = new Author();
+		a3.setName( "Moliere" );
+
+		Order o = new Order();
+		o.setOrderNumber( "ACVBNM");
+
+		Order o2 = new Order();
+		o2.setOrderNumber( "ZERTYD");
+
+		Product p1 = new Product();
+		p1.setName( "Candide" );
+		p1.getAuthors().add(a);
+		p1.getAuthors().add(a2); //be creative
+
+		Product p2 = new Product();
+		p2.setName( "Le malade imaginaire" );
+		p2.getAuthors().add(a3);
+		p2.getOrders().put("Emmanuel", o);
+		p2.getOrders().put("Gavin", o2);
+
+		
+		Session s = openSession( );
+		Transaction tx = s.beginTransaction();
+		s.persist( a );
+		s.persist( a2 );
+		s.persist( a3 );
+		s.persist( o );
+		s.persist( o2 );
+		s.persist( p1 );
+		s.persist( p2 );
+		tx.commit();
+
+		s.clear();
+
+		FullTextSession session = Search.createFullTextSession(s);
+        QueryParser parser = new MultiFieldQueryParser( new String[] {"name", "authors.name"}, new StandardAnalyzer() );
+        Query query;
+        List result;
+
+        query = parser.parse("Hugo");
+		result = session.createFullTextQuery(query, Product.class).list();
+        assertEquals( "collection of embedded ignored", 1, result.size() );
+
+		session = Search.createFullTextSession(s);
+        //parser = new MultiFieldQueryParser( new String[] {"name", "orders.orderNumber"}, new StandardAnalyzer() );
+		//query = parser.parse("ZERTYD");
+
+		//PhraseQuery
+		query = new TermQuery(new Term("orders.orderNumber", "ZERTYD"));
+		result = session.createFullTextQuery(query, Product.class).list();
+        assertEquals( "collection of untokenized ignored", 1, result.size() );
+		query = new TermQuery(new Term("orders.orderNumber", "ACVBNM"));
+		result = session.createFullTextQuery(query, Product.class).list();
+        assertEquals( "collection of untokenized ignored", 1, result.size() );
+
+		s.clear();
+
+		tx = s.beginTransaction();
+		s.delete( s.get(Product.class, p1.getId() ) );
+		s.delete( s.get(Product.class, p2.getId() ) );
+		tx.commit();
+		s.close();
+
+	}
+
 	protected Class[] getMappings() {
 		return new Class[] {
 				Tower.class,
-				Address.class
+				Address.class,
+				Product.class,
+				Order.class,
+				Author.class
 		};
 	}
 }

Added: trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Order.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Order.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Order.java	2007-04-20 19:04:07 UTC (rev 11420)
@@ -0,0 +1,42 @@
+//$Id: $
+package org.hibernate.search.test.embedded;
+
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.DocumentId;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+ at Table(name = "`Order`")
+public class Order {
+	@Id
+	@GeneratedValue
+	@DocumentId
+	private Integer id;
+	@Field(index= Index.UN_TOKENIZED)
+	private String orderNumber;
+	
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getOrderNumber() {
+		return orderNumber;
+	}
+
+	public void setOrderNumber(String orderNumber) {
+		this.orderNumber = orderNumber;
+	}
+}

Added: trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Product.java
===================================================================
--- trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Product.java	                        (rev 0)
+++ trunk/HibernateExt/search/src/test/org/hibernate/search/test/embedded/Product.java	2007-04-20 19:04:07 UTC (rev 11420)
@@ -0,0 +1,72 @@
+//$Id: $
+package org.hibernate.search.test.embedded;
+
+import java.util.Set;
+import java.util.Map;
+import java.util.HashSet;
+import java.util.HashMap;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Entity;
+import javax.persistence.ManyToMany;
+import javax.persistence.Column;
+import javax.persistence.CascadeType;
+
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.IndexedEmbedded;
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.annotations.MapKey;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+ at Indexed
+public class Product {
+	@Id @GeneratedValue @DocumentId
+	private Integer id;
+	@Field(index= Index.TOKENIZED)
+	private String name;
+	@ManyToMany(cascade = CascadeType.REMOVE) //just to make the test easier, cascade doesn't really make any business sense
+	@IndexedEmbedded
+	private Set<Author> authors = new HashSet<Author>();
+	@ManyToMany(cascade = CascadeType.REMOVE) //just to make the test easier, cascade doesn't really make any business sense
+	@MapKey(columns = @Column(name="CUST_NAME") )
+	@IndexedEmbedded
+	private Map<String, Order> orders = new HashMap<String, Order>();
+
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Set<Author> getAuthors() {
+		return authors;
+	}
+
+	public void setAuthors(Set<Author> authors) {
+		this.authors = authors;
+	}
+
+	public Map<String, Order> getOrders() {
+		return orders;
+	}
+
+	public void setOrders(Map<String, Order> orders) {
+		this.orders = orders;
+	}
+}




More information about the hibernate-commits mailing list