• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

understanding persistence

 
Alan Shiers
Ranch Hand
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'm trying to understand how persistence works and have been experimenting with a small app. Please read on and help me to understand if my findings are correct.

Note that given a class Foo that has a collection of Bar objects like so:

@Entity
@Table (name = "FOOS")
public class Foo
{
...
@OneToMany(mappedBy = "foo")
private Collection<Bar> BARS = new ArrayList<Bar>();
...
//getters and setters
}

Let us say that we have loaded the collection with three Bar objects. Now, let us say that we want to remove one of the Bar objects from the collection. My experimental app seems to indicate that it is not enough to simply call the remove(Object o) method on the collection, but one has to also call the remove(Object o) method on the EntityManager as well in order to get that record out of the BARS table of the database. Correct?

Furthormore, what if I wanted to remove the entire instance of the Foo object (this would include any and all remaining Bar objects in the collection)? Do I have to clear the entire collection of Bars first and those instances from the BARS table before I can remove the instance of the Foo object from the FOOS table of the database? Is there a way to do this all in one go with one method call? Does cascading help in some way in this scenario?

Please advise,

Alan
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is exactly what cascade is about. It tells an ORM how to handle the associations. In your example the cascade option that will do this for you is the "delete" option.

Mark
 
Alan Shiers
Ranch Hand
Posts: 237
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, if I want to delete the instance of Foo and all associated instances that are part of internal collections, by using the following code:

EntityManager em1 = emf.createEntityManager();
EntityTransaction tx1 = em1.getTransaction();
tx1.begin();
Foo foo = em1.find(Foo.class, new Long(1));
em1.remove(foo);
tx1.commit();
em1.close();

Should I then add the additional annotations to the class?

@Entity
@Table (name = "FOOS")
public class Foo
{
...
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy="foo")
@org.hibernate.annotations.Cascade org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@org.hibernate.annotations.CollectionOfElements
@joinTable(name = "BARS", joinColumns = @JoinColumn(name = "BAR_ID"))
private Collection<Bar> BARS = new ArrayList<Bar>();
...
//getters and setters
}

Or was what I had already enough? Because when I tried to run the app with the original annotation while doing a remove(), hibernate threw an exception because, according to the SQL log, it tried to perform a delete on one of the collection instances, and of course that instance wasn't in scope of the persistence context. This is why I'm asking these questions because hibernates behaviour seems to indicate that it was trying to also remove that instance from the collection even though my mapping was simply thus:

@Entity
@Table (name = "FOOS")
public class Foo
{
...
@OneToMany(mappedBy="foo")
private Collection<Bar> BARS = new ArrayList<Bar>();
...
//getters and setters
}

Which is the best way to map this scenario? Perhaps it's better to be more explicit with the cascade annotations?


Alan

[ February 11, 2007: Message edited by: Alan Shiers ]

[ February 11, 2007: Message edited by: Alan Shiers ]
[ February 11, 2007: Message edited by: Alan Shiers ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic