2

I am using JPA2.O with Hibernate. I have one to many relationship between User and Address and I have below configuration with this relationship:

cascade = CascadeType.ALL, fetch = FetchType.LAZY,

For example I have below entries in database tables:

User Table

Column: UserID | UserName
row1:    User1 | UserName

Address Table

Column: AddressId| UserID | Address    

row1:   Address1 | User1  | Actual Address

row2:   Address2 | User1  | Actual Address

I can fetch User entity using find by userId:

User user = entityManager.find(User.class, userId);

And also can fetch Answers using user.getAddresses(). Code for getAddressess() is like below:

public class User{
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
    public Set<Address> getAddresses() {
       return this.addresses;
    }
}

Now what I am trying to do, I am fetching the set of addresses and removing one entry. Let say I fetched addressess set first time I have address 1 and 2. I removed address 2 entity from set of addresses. Now User entity is pointing to the Set which is having only 1 entry that is for Address1.

Now If I merge user entity using below method, I think, row for address 2 should be deleted from address table. But it is not happening. Am I missing any thing or it is not a way to do it. Please suggest.

entityManager.merge(user); 
Narendra Verma
  • 2,372
  • 6
  • 34
  • 61
  • 1) suggest to change to @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user", orphanRemoval = true) 2) please provide more code for frist and second cases – Michail Nikolaev Mar 20 '13 at 15:24
  • Thanks Michail. This worked for me. I also got a very nice description from here http://stackoverflow.com/questions/4329577/jpa-2-0-orphanremoval-true-vs-on-delete-cascade. – Narendra Verma Mar 21 '13 at 07:21

1 Answers1

3

Just want to add more detail as I got this working.

I added orphanRemoval = true with @OneToMany relationship:

public class User{
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "user")
    public Set<Address> getAddresses() {
       return this.addresses;
    }
}

After changing my code I re-tested it and got below error:

Caused by: org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance:

This link helped me to solve above problem:

Now I can delete the child entities from database, if those are disconnected(removed) from defined collection in parent entity.

Narendra Verma
  • 2,372
  • 6
  • 34
  • 61
  • link provided is broken – rajadilipkolli May 13 '18 at 01:32
  • Thanks a lot. orphanRemoval = true, solved my issue. I also used 'fetch = FetchType.EAGER'. I saw in other questions programmers have advised remove 'fetch = FetchType.EAGER'. But for me it worked. If I remove 'fetch = FetchType.EAGER' then my update fails. I configured my parent entity as this: @OneToMany(mappedBy = "objWatchList", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) – Yeshwant KAKAD Apr 12 '19 at 07:47
  • Good to hear that it worked for you. Enjoy coding !! – Narendra Verma Apr 17 '19 at 16:12