-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Hibernate EJB3 persist cascade problem
PostPosted: Wed Jan 31, 2007 2:25 pm 
Newbie

Joined: Wed Jan 31, 2007 2:00 pm
Posts: 8
Location: Canada
We have recently moved from Hibernate to Hibernate with EJB3, and we have many bi-directional and uni-directional relationships between our classes. while persisting an object, (using the persist method of entitymanager), something wierd happens: unlike Hibernate, seemingly the call to persist method calls persist on ALL
persistent members that have a cascade type of persist. As a result, many "select" queries are generated for the many relationships that we have and finally a timeout occurs without persisting the object and its new fields (seemingly the cascade occures in a very large range which is a lot more than what we excpet, instead of only persisting that class and the few new children) ... Any ideas how we can solve this problem?

Hibernate version: 3

Relationship Example:

Just one example:

In SuggestedTrade Class:

@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
@JoinColumn(name = "ofId")
private PersistentSecurity of;

In PersistentSecurity Class:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "of" , cascade = { CascadeType.PERSIST } )
private Set<SuggestedTrade> trades;

_________________
Sara


Top
 Profile  
 
 Post subject: Re: Hibernate EJB3 persist cascade problem
PostPosted: Wed Jan 31, 2007 5:54 pm 
Regular
Regular

Joined: Mon Nov 14, 2005 7:33 pm
Posts: 73
saraxyz wrote:
We have recently moved from Hibernate to Hibernate with EJB3, and we have many bi-directional and uni-directional relationships between our classes. while persisting an object, (using the persist method of entitymanager), something wierd happens: unlike Hibernate, seemingly the call to persist method calls persist on ALL
persistent members that have a cascade type of persist. As a result, many "select" queries are generated for the many relationships that we have and finally a timeout occurs without persisting the object and its new fields (seemingly the cascade occures in a very large range which is a lot more than what we excpet, instead of only persisting that class and the few new children) ... Any ideas how we can solve this problem?

Hibernate version: 3

Relationship Example:

Just one example:

In SuggestedTrade Class:

@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
@JoinColumn(name = "ofId")
private PersistentSecurity of;

In PersistentSecurity Class:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "of" , cascade = { CascadeType.PERSIST } )
private Set<SuggestedTrade> trades;


That seems odd, try (just for the sake of testing), changing your cascades to look like so:

cascade=CascadeType.ALL

See if the problem "goes away" - if not, there must be something else going on in your code to cause the extra activity that you're not aware of or just overlooking.

I use all types of cascading w/ the current version of Hibernate and have not experienced this.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 02, 2007 6:12 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Which version are you using exactly?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 12:40 am 
Newbie

Joined: Wed Jan 31, 2007 2:00 pm
Posts: 8
Location: Canada
Hibernate-Version: 3.2.0.ga
Database: Microsoft SQL Server 2005

We removed some of the cascades in one side of the bidirectional relationships and it has got a bit better (at least it goes through persisting) but this is not the right solution, as eventually we might need those cascades .. I am wondering maybe other people have not encountered this problem because their table relationships have not been as deep?

thanks ...

_________________
Sara


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 7:25 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I must admit I don't really understand your problem, you're telling me Hibernate initialize lazy objects traversed by the persist operation?
I guess a simple runnable test case will be needed

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 12:22 pm 
Newbie

Joined: Wed Jan 31, 2007 2:00 pm
Posts: 8
Location: Canada
Yess exactly; hibernate initialize lazy objects traversed by the persist operation, and this is our problem. I will send you a test case soon.

_________________
Sara


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 5:43 pm 
Newbie

Joined: Wed Jan 31, 2007 2:00 pm
Posts: 8
Location: Canada
I couldn't find a way to attach the project to this reply; but here is the test case:

class A has bidirectional one-to-many relationship to classes B1, B2, B3, B4
(b1List, b2List, b3List, b4List)

B1 has bidirectional one-to-many relationship to C1
(c1List)

B2 has bidirectional one-to-many relationship to C2
(c2List)

as follows:

Code:
package com.test.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.OptimisticLockType;

@Entity
@AccessType("field")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@org.hibernate.annotations.Entity(optimisticLock=OptimisticLockType.VERSION)
public class A {
   
   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   private int id;
   
   private String name;
   
   @OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
   private Set<B1> b1List;
   
   @OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
   private Set<B2> b2List;
   
   @OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
   private Set<B3> b3List;
   
   @OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
   private Set<B4> b4List;

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public Set<B1> getB1List() {
      if(b1List == null)
         b1List = new HashSet<B1>();
      return b1List;
   }

   public void setB1List(Set<B1> list) {
      b1List = list;
   }

   public Set<B2> getB2List() {
      if(b2List == null)
         b2List = new HashSet<B2>();
      return b2List;
   }

   public void setB2List(Set<B2> list) {
      b2List = list;
   }

   public Set<B3> getB3List() {
      return b3List;
   }

   public void setB3List(Set<B3> list) {
      if(b3List == null)
         b3List = new HashSet<B3>();
      b3List = list;
   }

   public Set<B4> getB4List() {
      return b4List;
   }

   public void setB4List(Set<B4> list) {
      if(b4List == null)
         b4List = new HashSet<B4>();
      b4List = list;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
   
   
}


Code:
package com.test.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.OptimisticLockType;


@Entity
@AccessType("field")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@org.hibernate.annotations.Entity(optimisticLock=OptimisticLockType.VERSION)
public class B1 {
   
   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   private int id;
   
   @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
   @JoinColumn(name = "aId")
   private A a;

   @OneToMany(fetch = FetchType.LAZY, mappedBy="b1", cascade = {CascadeType.PERSIST})
   private Set<C1> c1List;

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public A getA() {
      return a;
   }

   public void setA(A a) {
      this.a = a;
   }

   public Set<C1> getC1List() {
      if(c1List == null)
         c1List = new HashSet<C1>();
      return c1List;
   }

   public void setC1List(Set<C1> list) {
      c1List = list;
   }
}


(other classes are just the same, so I don't copy their code here)

I have entered data in quite all of the tables.

Now, when I run the following code which finds an object of type A, and in its b2List finds an object of type B2, and then adds a C2 to this B2 and persists the C2:

Code:
      A a = em.find(A.class, 1);
      C2 c2 = new C2();
      for(B2 b2:a.getB2List())
      {
         if(b2.getId() == 1)
         {
            b2.getC2List().add(c2);
            c2.setB2(b2);
         }
      }
      em.persist(c2);


Here is what I will see after the line em.persist(c2) is executed:

Code:
16:08:32,296 INFO  [STDOUT] Hibernate: select a0_.id as id0_0_, a0_.name as name0_0_ from A a0_ where a0_.id=?
16:08:32,375 INFO  [STDOUT] Hibernate: select b2list0_.aId as aId1_, b2list0_.id as id1_, b2list0_.id as id2_0_, b2list0_.aId as aId2_0_ from B2 b2list0_ where b2list0_.aId=?
16:08:32,390 INFO  [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,421 INFO  [STDOUT] Hibernate: select b1list0_.aId as aId1_, b1list0_.id as id1_, b1list0_.id as id1_0_, b1list0_.aId as aId1_0_ from B1 b1list0_ where b1list0_.aId=?
16:08:32,437 INFO  [STDOUT] Hibernate: select c1list0_.b1Id as b2_1_, c1list0_.id as id1_, c1list0_.id as id5_0_, c1list0_.b1Id as b2_5_0_ from C1 c1list0_ where c1list0_.b1Id=?
16:08:32,453 INFO  [STDOUT] Hibernate: select c1list0_.b1Id as b2_1_, c1list0_.id as id1_, c1list0_.id as id5_0_, c1list0_.b1Id as b2_5_0_ from C1 c1list0_ where c1list0_.b1Id=?
16:08:32,453 INFO  [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,453 INFO  [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,453 INFO  [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,453 INFO  [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,468 INFO  [STDOUT] Hibernate: select b3list0_.aId as aId1_, b3list0_.id as id1_, b3list0_.id as id3_0_, b3list0_.aId as aId3_0_ from B3 b3list0_ where b3list0_.aId=?
16:08:32,468 INFO  [STDOUT] Hibernate: select b4list0_.aId as aId1_, b4list0_.id as id1_, b4list0_.id as id4_0_, b4list0_.aId as aId4_0_ from B4 b4list0_ where b4list0_.aId=?
16:08:32,531 INFO  [STDOUT] Hibernate: insert into C2 (b2Id) values (?)


The question is, if I am persisting C2, why is it initializing C1 or B4, or other existing C2's?
In our application as the relationships are more complicated and there is a lot of data, this will result in a timeout, so that in some cases it never reaches the very last line (insert).

Thanks for your time

_________________
Sara


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 6:58 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I re;e;ber a bug similar a long time ago, can you give it a try with 3.2.2
If it fails, attach it to a JIRa case http://opensource.atlassian.com/projects/hibernate/secure/Dashboard.jspa

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 06, 2007 12:38 pm 
Newbie

Joined: Wed Jan 31, 2007 2:00 pm
Posts: 8
Location: Canada
I tried hibernate3.jar 3.2.2 and hibernate-entitymanager.jar 3.2.1.ga (I assume that's the latest version available) but unfortunately it didn't help ... I created an issue in Jira/Hibernate Entity Manager.

_________________
Sara


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 8:32 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Thanks

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 11, 2008 6:59 am 
Newbie

Joined: Wed Jun 11, 2008 6:53 am
Posts: 1
Hi,

i am facing same troubles with the Hibernate-Version: 3.2.4.sp1, so can anyone please tell me if this is really a bug and if it is fixed or not? or is it a matter of coding that we should deal with it differently!

thank you


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.