Here I am writing to cover up the difference between OrphanRemoval=true and CascadeType.REMOVE in JPA2.0 with hibernate.
Let say there is one to many relationship between User and Address and that can be defined in JPA as below:
public class User{
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
mappedBy = "user") public Set
getAddresses() { return this.addresses; } }
public class Address{
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="userid")
public User getUser() {
return this.user;
}
}
You can have more detail in this post about above entities.
If I want to fetch the user entity and corresponding addresses, I can use below piece of code:
EntityManagerFactory emf
= Persistence.createEntityManagerFactory("StateCityService");
EntityManager entityManager= emf.createEntityManager();
//fetching user entity based on id
User user = entityManager.find(User.class, userId);
Set addresses = user.getAddresses();
// Lazy loading of addresses
Now if I change any
state of user or address entity and execute merge operation on user
entity, then corresponding User's and Address table's column value will
be updated.
entityManager.merge(user);
That
means, If I remove couple of address items from the set which user
entity holds and perform merge operation on user entity, corresponding
address rows (which have been removed from the collection defined in
user entity) should be deleted based on
CascadeType.ALL(add/remove/update). What do you think? You might answer
yes. Even I think so.
But not really, CascadeType.REMOVE dose not help you in this scenario.
Achieving
same thing in my project I invested couple of ours and found the
solution. I had to use OrphanRemoval=true with one to many relationship
to achieve this.
public class User{
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
orphanRemoval=true, mappedBy = "user")
public Set getAddresses() {
return this.addresses;
}
}
'OrphanRemoval=true' Vs 'CascadeType.REMOVE'
The difference between the two settings is in the response to
removing child objects from the collection pointed by parent entity.
If
orphanRemoval=true is specified the removed address instance is
automatically removed. If only cascade=CascadeType.REMOVE is specified
no automatic action is taken since removing a relationship is not a
remove operation.
Where 'OrphanRemoval=true' and 'CascadeType.REMOVE' are identical ?
When
an User entity object is removed the remove operation is cascaded to
the referenced Address entity object. In this case, orphanRemoval=true
and cascade=CascadeType.REMOVE are identical.
Use this link to have more detail.
No comments:
Post a Comment