Author: epbernard
Date: 2010-04-09 11:36:40 -0400 (Fri, 09 Apr 2010)
New Revision: 19200
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForDoc0.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForUnindexed.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForDoc0.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForUnindexed.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/LazyM2OContainedInTest.java
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
Log:
HSEARCH-386 Avoid LIE when processing containedIn collections
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java
===================================================================
---
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java 2010-04-09
09:50:30 UTC (rev 19199)
+++
search/trunk/hibernate-search/src/main/java/org/hibernate/search/engine/DocumentBuilderContainedEntity.java 2010-04-09
15:36:40 UTC (rev 19200)
@@ -642,10 +642,27 @@
}
}
else if ( member.isCollection() ) {
- Collection<T> collection = getActualCollection( member, value );
- for ( T collectionValue : collection ) {
- processSingleContainedInInstance( queue, searchFactoryImplementor, collectionValue
);
+ Collection<T> collection = null;
+ try {
+ collection = getActualCollection( member, value );
+ collection.size(); //load it
}
+ catch ( Exception e ) {
+ if ( e.getClass().getName().contains(
"org.hibernate.LazyInitializationException" ) ) {
+ /* A deleted entity not having its collection initialized
+ * leads to a LIE because the colleciton is no longer attached to the session
+ *
+ * But that's ok as the collection update event has been processed before
+ * or the fk would have been cleared and thus triggering the cleaning
+ */
+ collection = null;
+ }
+ }
+ if ( collection != null ) {
+ for ( T collectionValue : collection ) {
+ processSingleContainedInInstance( queue, searchFactoryImplementor, collectionValue
);
+ }
+ }
}
else {
processSingleContainedInInstance( queue, searchFactoryImplementor, value );
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForDoc0.java
===================================================================
---
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForDoc0.java
(rev 0)
+++
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForDoc0.java 2010-04-09
15:36:40 UTC (rev 19200)
@@ -0,0 +1,59 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import java.io.Serializable;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Version;
+
+/**
+ * Entite 1
+ *
+ * @author grolland
+ */
+(a)javax.persistence.Entity
+(a)org.hibernate.annotations.Proxy(lazy = true)
+(a)org.hibernate.search.annotations.Indexed
+(a)javax.persistence.Table(name = "entity1")
+//@SequenceGenerator( name="ids_generator1", sequenceName =
"ids_generator1")
+public class Entity1ForDoc0 implements Serializable {
+
+ private static final long serialVersionUID = -3191273589083411349L;
+
+ @Id
+ @GeneratedValue //(generator = "ids_generator1", strategy =
GenerationType.SEQUENCE)
+ private long uid;
+
+ @Version
+ private int optlock;
+
+ @javax.persistence.OneToMany(mappedBy = "entity1", cascade = { })
+ @org.hibernate.search.annotations.IndexedEmbedded
+ private java.util.List<Entity2ForDoc0> entities2 = new
java.util.ArrayList<Entity2ForDoc0>();
+
+ public long getUid() {
+ return uid;
+ }
+
+ public void setUid(final long uid) {
+ this.uid = uid;
+ }
+
+ public int getOptlock() {
+ return optlock;
+ }
+
+ public void setOptlock(final int optlock) {
+ this.optlock = optlock;
+ }
+
+ public void setEntities2(final java.util.List<Entity2ForDoc0> entities2) {
+ this.entities2 = entities2;
+ }
+
+ public java.util.List<Entity2ForDoc0> getEntities2() {
+ return entities2;
+ }
+
+}
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForUnindexed.java
===================================================================
---
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForUnindexed.java
(rev 0)
+++
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity1ForUnindexed.java 2010-04-09
15:36:40 UTC (rev 19200)
@@ -0,0 +1,94 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import java.io.Serializable;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Version;
+
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+
+/**
+ * Entite 1
+ *
+ * @author grolland
+ */
+(a)javax.persistence.Entity
+(a)org.hibernate.annotations.Proxy(lazy = false)
+(a)org.hibernate.annotations.Cache(usage =
org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
+(a)javax.persistence.Table(name = "entity1")
+public class Entity1ForUnindexed implements Serializable {
+
+ private static final long serialVersionUID = -3191273589083411349L;
+
+ @Id
+ @GeneratedValue
+ @Field(index = Index.UN_TOKENIZED)
+ private long uid;
+
+ @Version
+ private int optlock;
+
+ @javax.persistence.OneToMany(mappedBy = "entity1", cascade = { })
+ @org.hibernate.search.annotations.ContainedIn
+ @org.hibernate.annotations.Cache(usage =
org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
+ private java.util.List<Entity2ForUnindexed> entities2 = new
java.util.ArrayList<Entity2ForUnindexed>();
+
+ /**
+ * Getter de l'attribut uid
+ *
+ * @return long : Renvoie uid.
+ */
+ public long getUid() {
+ return uid;
+ }
+
+ /**
+ * Setter de l'attribut uid
+ *
+ * @param uid uid a definir.
+ */
+ public void setUid(long uid) {
+ this.uid = uid;
+ }
+
+ /**
+ * Getter de l'attribut optlock
+ *
+ * @return int : Renvoie optlock.
+ */
+ public int getOptlock() {
+ return optlock;
+ }
+
+ /**
+ * Setter de l'attribut optlock
+ *
+ * @param optlock optlock a definir.
+ */
+ public void setOptlock(int optlock) {
+ this.optlock = optlock;
+ }
+
+ /**
+ * Setter de l'attribut entities2
+ *
+ * @param entities2 entities2 a definir.
+ */
+ public void setEntities2(java.util.List<Entity2ForUnindexed> entities2) {
+ this.entities2 = entities2;
+ }
+
+ /**
+ * Getter de l'attribut entities2
+ *
+ * @return java.util.List<Entity2> : Renvoie entities2.
+ */
+ public java.util.List<Entity2ForUnindexed> getEntities2() {
+ return entities2;
+ }
+
+}
+
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForDoc0.java
===================================================================
---
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForDoc0.java
(rev 0)
+++
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForDoc0.java 2010-04-09
15:36:40 UTC (rev 19200)
@@ -0,0 +1,67 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import javax.persistence.Basic;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Version;
+
+/**
+ * @author grolland
+ *
+ */
+(a)javax.persistence.Entity
+(a)org.hibernate.annotations.Proxy(lazy = true)
+(a)javax.persistence.Table(name = "entity2")
+// @SequenceGenerator( name="ids_generator2", sequenceName =
"ids_generator2")
+public class Entity2ForDoc0 {
+
+ private static final long serialVersionUID = -3191273589083411349L;
+
+ @Id
+ @GeneratedValue //(generator = "ids_generator2", strategy =
GenerationType.SEQUENCE)
+ private long uid;
+
+ @Version
+ private int optlock;
+
+ @javax.persistence.ManyToOne(cascade = { }, fetch = javax.persistence.FetchType.LAZY)
+ @org.hibernate.search.annotations.ContainedIn
+ private Entity1ForDoc0 entity1;
+
+ @Basic
+ private String name = null;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public long getUid() {
+ return uid;
+ }
+
+ public void setUid(final long uid) {
+ this.uid = uid;
+ }
+
+ public int getOptlock() {
+ return optlock;
+ }
+
+ public void setOptlock(final int optlock) {
+ this.optlock = optlock;
+ }
+
+ public void setEntity1(final Entity1ForDoc0 entity1) {
+ this.entity1 = entity1;
+ }
+
+ public Entity1ForDoc0 getEntity1() {
+ return entity1;
+ }
+}
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForUnindexed.java
===================================================================
---
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForUnindexed.java
(rev 0)
+++
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/Entity2ForUnindexed.java 2010-04-09
15:36:40 UTC (rev 19200)
@@ -0,0 +1,96 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Version;
+
+/**
+ * Entite 2
+ *
+ * @author grolland
+ */
+(a)javax.persistence.Entity
+(a)org.hibernate.annotations.Proxy(lazy = false)
+(a)org.hibernate.annotations.Cache(usage =
org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
+(a)javax.persistence.Table(name = "entity2")
+(a)org.hibernate.search.annotations.Indexed
+public class Entity2ForUnindexed {
+ /**
+ * Commentaire pour <code>serialVersionUID</code>
+ */
+ private static final long serialVersionUID = -3191273589083411349L;
+
+ /**
+ * Identifiant unique
+ */
+ @Id
+ @GeneratedValue
+ private long uid;
+
+ /**
+ * Controle de version optimiste
+ */
+ @Version
+ private int optlock;
+
+ @javax.persistence.ManyToOne(cascade = { }, fetch = javax.persistence.FetchType.LAZY)
+ @org.hibernate.search.annotations.IndexedEmbedded()
+ @org.hibernate.annotations.Cache(usage =
org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
+ private Entity1ForUnindexed entity1;
+
+ /**
+ * Getter de l'attribut uid
+ *
+ * @return long : Renvoie uid.
+ */
+ public long getUid() {
+ return uid;
+ }
+
+ /**
+ * Setter de l'attribut uid
+ *
+ * @param uid uid a definir.
+ */
+ public void setUid(long uid) {
+ this.uid = uid;
+ }
+
+ /**
+ * Getter de l'attribut optlock
+ *
+ * @return int : Renvoie optlock.
+ */
+ public int getOptlock() {
+ return optlock;
+ }
+
+ /**
+ * Setter de l'attribut optlock
+ *
+ * @param optlock optlock a definir.
+ */
+ public void setOptlock(int optlock) {
+ this.optlock = optlock;
+ }
+
+ /**
+ * Setter de l'attribut entity1
+ *
+ * @param entity1 entity1 a definir.
+ */
+ public void setEntity1(Entity1ForUnindexed entity1) {
+ this.entity1 = entity1;
+ }
+
+ /**
+ * Getter de l'attribut entity1
+ *
+ * @return Entity1 : Renvoie entity1.
+ */
+ public Entity1ForUnindexed getEntity1() {
+ return entity1;
+ }
+}
Added:
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/LazyM2OContainedInTest.java
===================================================================
---
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/LazyM2OContainedInTest.java
(rev 0)
+++
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/embedded/nested/containedIn/LazyM2OContainedInTest.java 2010-04-09
15:36:40 UTC (rev 19200)
@@ -0,0 +1,129 @@
+package org.hibernate.search.test.embedded.nested.containedIn;
+
+import java.util.List;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.TermQuery;
+
+import org.hibernate.Transaction;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.test.SearchTestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class LazyM2OContainedInTest extends SearchTestCase {
+
+ //HSEARCH-385
+ public void testDocumentsAt0() {
+ FullTextSession fts = Search.getFullTextSession( getSessions().openSession() );
+ Transaction tx = fts.beginTransaction();
+ final Entity1ForDoc0 ent1 = new Entity1ForDoc0();
+ final Entity2ForDoc0 ent2 = new Entity2ForDoc0();
+
+ ent2.setEntity1( ent1 );
+ ent1.getEntities2().add( ent2 );
+
+ ent2.setName( "test - 1" );
+
+ fts.persist( ent1 );
+ fts.persist( ent2 );
+
+ tx.commit();
+
+ long uid2 = ent2.getUid();
+ long uid1 = ent1.getUid();
+
+
+ fts.clear();
+
+ tx = fts.beginTransaction();
+
+ assertEquals( 1, fts.createFullTextQuery( new TermQuery( new Term("uid", new
Long(uid1).toString() ) ), Entity1ForDoc0.class ).getResultSize() );
+ assertEquals( 1, fts.createFullTextQuery( new TermQuery( new
Term("entities2.uid", new Long(uid2).toString() ) ), Entity1ForDoc0.class
).getResultSize() );
+
+
+ tx.commit();
+
+ tx = fts.beginTransaction();
+ for ( Entity2ForDoc0 e : (List<Entity2ForDoc0>) fts.createCriteria(
Entity2ForDoc0.class ).list() ) {
+ fts.delete( e );
+ }
+ for ( Entity1ForDoc0 e : (List<Entity1ForDoc0>) fts.createCriteria(
Entity1ForDoc0.class ).list() ) {
+ fts.delete( e );
+ }
+ tx.commit();
+ }
+
+ //HSEARCH-386
+ public void testContainedInAndLazy() {
+ FullTextSession fts = Search.getFullTextSession( getSessions().openSession() );
+ Entity1ForUnindexed ent1_0 = new Entity1ForUnindexed();
+ Entity1ForUnindexed ent1_1 = new Entity1ForUnindexed();
+
+ Entity2ForUnindexed ent2_0 = new Entity2ForUnindexed();
+ Entity2ForUnindexed ent2_1 = new Entity2ForUnindexed();
+
+ ent2_0.setEntity1(ent1_0);
+ ent1_0.getEntities2().add(ent2_0);
+
+ ent2_1.setEntity1(ent1_1);
+ ent1_1.getEntities2().add(ent2_1);
+
+ //persist outside the tx
+ fts.persist(ent1_0);
+ fts.persist(ent1_1);
+ fts.persist(ent2_0);
+ fts.persist(ent2_1);
+
+ Transaction tx = fts.beginTransaction();
+ tx.commit(); //flush
+
+ fts.clear();
+
+ Entity1ForUnindexed other = new Entity1ForUnindexed();
+ fts.persist(other);
+
+ fts.getTransaction().begin();
+ fts.getTransaction().commit();
+ fts.clear();
+
+ //FIXME that's not guaranteed to happen before flush
+ long otherId = other.getUid();
+
+ assertEquals( 1, fts.createFullTextQuery( new TermQuery( new
Term("entity1.uid", new Long( ent1_0.getUid() ).toString() ) ),
Entity2ForUnindexed.class ).getResultSize() );
+ Entity1ForUnindexed toDelete = (Entity1ForUnindexed) fts.get(Entity1ForUnindexed.class,
otherId);
+
+ fts.delete(toDelete);
+
+ fts.getTransaction().begin();
+ fts.getTransaction().commit();
+ fts.clear();
+
+ assertEquals( 0, fts.createFullTextQuery( new TermQuery( new
Term("entity1.uid", new Long(otherId).toString() ) ), Entity2ForUnindexed.class
).getResultSize() );
+
+ tx = fts.beginTransaction();
+ for ( Entity2ForUnindexed e : (List<Entity2ForUnindexed>) fts.createCriteria(
Entity2ForUnindexed.class ).list() ) {
+ fts.delete( e );
+ }
+ for ( Entity1ForUnindexed e : (List<Entity1ForUnindexed>) fts.createCriteria(
Entity1ForUnindexed.class ).list() ) {
+ fts.delete( e );
+ }
+ tx.commit();
+
+ fts.close();
+ }
+
+
+
+ @Override
+ protected Class<?>[] getMappings() {
+ return new Class<?>[] {
+ Entity1ForDoc0.class,
+ Entity2ForDoc0.class,
+ Entity1ForUnindexed.class,
+ Entity2ForUnindexed.class
+ };
+ }
+}