-->
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.  [ 10 posts ] 
Author Message
 Post subject: delete object from collection
PostPosted: Fri Sep 02, 2005 5:01 pm 
Newbie

Joined: Fri Sep 02, 2005 4:00 pm
Posts: 7
Location: Poland
Hi
I'm working with ejb 3.0 (jboss 4.0.3 rc2).

I have two classess:

Code:
@Entity
@Table(name="parents")
public class Parent implements Serializable {
   private Integer idparent;
   private String name;
   private List<Child> children;
   
   @Id(generate=GeneratorType.AUTO)
   @Column(name="idparent")
   public Integer getIdparent() {
      return idparent;
   }
   public void setIdparent(Integer idparent) {
      this.idparent = idparent;
   }
   
   @Column(name="name")
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   
   @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
   public List<Child> getChildren() {
      return children;
   }
   public void setChildren(List<Child> children) {
      this.children = children;
   }
}



Code:
@Entity
@Table(name="children")
public class Child implements Serializable {
   private Integer idchild;
   private String name;
   private Parent parent;
   
   @Id(generate=GeneratorType.AUTO)
   @Column(name="idchild")
   public Integer getIdchild() {
      return idchild;
   }
   public void setIdchild(Integer idchild) {
      this.idchild = idchild;
   }
   
   @Column(name="name")
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   
   @ManyToOne
   @JoinColumn(name="parent")
   public Parent getParent() {
      return parent;
   }
   public void setParent(Parent parent) {
      this.parent = parent;
   }   
}



I have stateless session bean which contains methods:

Code:
public void updateParent(Parent p) {
  em.merge(p);      // entity manager
}
public List<Parent> getParents() {
  return em.createQuery("from Parent p").getResultList();
}


in my client application there is something like this:
Code:
Context context = new InitialContext();
Information inf = (Information)context.lookup(Information.class.getName());
Parent p = inf.getParents().iterator().next();         
Child c = p.getChildren().iterator().next();
p.getChildren().remove(c);
c.setParent(null);
inf.updateParent(p);


In my opinion it should be OK, but this code doesn't delete anything in DB.
Adding new objects works good.
I was trying cascade (ALL and ORPHAN-DELETE) but i had the same problem.

What should I fix? How to delete object from collection?

Sorry for my english!!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 03, 2005 8:30 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
as is this stuff can't work because, Hibernate has no notion of the removed children since you pass it =back the parent object (wo link to the removed children anymore)

The solution is cascade delete orphan in the @OneToMany

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 03, 2005 4:50 pm 
Newbie

Joined: Fri Sep 02, 2005 4:00 pm
Posts: 7
Location: Poland
Hi,
thanks for your reply.

this is my code: (using delete-orphan)

Code:
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@org.hibernate.annotations.Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN})
   public List<Child> getChildren() {
      return children;
   }
   public void setChildren(List<Child> children) {
      this.children = children;
   }
}


And my client code:

Code:
Parent p = inf.getParents().iterator().next();
Child c = p.getChildren().iterator().next();
c.setParent(null)
p.getChildren().remove(c);
inf.updateParent(p);


It still doesn't work properly. On output (show_sql="true") hibernate writes only [STDOUT] Hibernate: select (...)
How to implement it?

Cheers.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 03, 2005 5:34 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Check the unit test suite, there is a testCascadeDeleteOrphan() method (see link)
http://cvs.sourceforge.net/viewcvs.py/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/OneToManyTest.java?rev=1.10&view=auto

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 03, 2005 7:12 pm 
Newbie

Joined: Fri Sep 02, 2005 4:00 pm
Posts: 7
Location: Poland
Thanks for reply, and very good link!
but...
It still doesn't work :/


Code:
Troop disney = new Troop();
disney.setName("Disney");
Soldier mickey = new Soldier();
mickey.setName("Mickey");
disney.addSoldier(mickey);
s.persist(disney);

It is such like piece of my code:

Code:
Parent p = new Parent();
p.setName("Krystyna");
Child c = new Child();
c.setName("Andrzej");
p.addChild(c);
inf.saveParent(p);       // stateless session bean where is em.persist(p);


It works good, but... (code from session bean)

Code:
Parent p = em.find(Parent.class, new Integer(9));
Child c = p.getChildren().iterator().next();
p.getChildren().remove(c);
em.merge(p);


It doesn't delete anything, but in my opinion it is quite like:

Code:
Troop troop = (Troop) s.get( Troop.class, disney.getId() );
Soldier soldier = (Soldier) troop.getSoldiers().iterator().next();
troop.getSoldiers().remove(soldier);


I have the same annotations like in Tropp, and Soldier classess.
Any ideas?

greet


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 06, 2005 3:38 am 
Newbie

Joined: Tue Sep 06, 2005 3:34 am
Posts: 3
I was seeing this error too, however I found when I removed the cascade attribute completly then it started working fine. I need to test this further but my impression is that the children are being removed and updated properly.

My mappings and code were very similar to the above postings.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 06, 2005 6:28 pm 
Newbie

Joined: Tue Sep 06, 2005 3:34 am
Posts: 3
My above posting was incorrect, without the cascade the child objects are not persisted, which is what I expected to happen. I have noticed from the Logs that delete orphans is being called on the collection, however no orphan objects are being found, the log entry looks like this:

Quote:
DEBUG main org.hibernate.engine.Cascades - deleting orphans for collection: -------

DEBUG main org.hibernate.engine.Cascades - done deleting orphans for collection: --------


This implies to me that the parent-child relationship is not setup properly or that there is a hanging reference to the child object that is stopping it from being considered an orphan. Please advise if you have any suggestions for the mapping.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 06, 2005 7:28 pm 
Newbie

Joined: Fri Sep 02, 2005 4:00 pm
Posts: 7
Location: Poland
Hi

Thanks for reply

I decided to change mappings, and now I have something like this:

Code:
@OneToMany(fetch=FetchType.EAGER,cascade=javax.persistence.CascadeType.ALL)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@JoinTable(table=@Table(name="parents_children"),
        joinColumns=@JoinColumn(name="idparent"),
        inverseJoinColumns=@JoinColumn(name="idchild"))
public List<Child> getChildren() {
    return children;
}
   
public void setChildren(List<Child> children){
    this.children = children
}


Code:
@ManyToOne
@JoinColumn(name="parent")
public Parent getParent() {
  return dzialprzemyslu;
}
public void setParent(Parent parent) {
this.parent = parent
}


It works properly, but how to make it without creating join table? (parents_children)

Do you have any ideas?

greet


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 07, 2005 6:05 pm 
Newbie

Joined: Tue Sep 06, 2005 3:34 am
Posts: 3
I found that my error was that I was not calling Commit and Close after doing my create. Once I added code to Commit and Close after the create of the parent then retrieved the object and removed the orphans it worked fine. Psuedo code for what I did is as follows:

Code:
Create Parent
Commit and Close
Retrieve Parent
Orphan Children
Commit and Close


From my understanding of Hibernate I am guessing that it would have seen the non commited orphaned children as 'dirty' records rather than 'orphaned' records.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 08, 2005 4:46 am 
Newbie

Joined: Fri Sep 02, 2005 4:00 pm
Posts: 7
Location: Poland
Hi

Is there any way to do it with container-managed EntityManager?
I can't close session...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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.