3

Having read JPA 2.0 / Hibernate and "orphanRemoval": Just replacing an entity does not remove the old one, and the related ticket https://hibernate.atlassian.net/browse/HHH-6484, I inferred that this had been (finally) fixed in version 4.2.7 and 4.3.0.CR1.

However, trying

...
entityManager.getTransaction().begin();
Point point = entityManager.find(Point.class, pointId);
point.setPost(null);
entityManager.getTransaction().commit();
...

where

public class Point {
    ...
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private Post post;
    ...
    public void setPost(Post post) {
        this.post = post;
    }
}

still does not make Hibernate issue a DELETE SQL statement for the target Post entity.

So has this @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) issue been fixed or not? and if so, how do I get the orphans to be deleted? Many thanks!

EDIT: After reading your answer, I noted that I (mistakenly) omitted to specify that the fetch=FetchType.LAZY in my mapping above.

Community
  • 1
  • 1
VH-NZZ
  • 5,248
  • 4
  • 31
  • 47
  • I tested with 4.2.2 version, All cases worked. bidirectional, unidirectional also worked. – Jayasagar Nov 29 '13 at 09:59
  • Following my question EDIT, reverting to default fetch mode to `FetchType.EAGER` **does remove the orphan** when calling - `setPost(null)` in **both 4.2.6** and **4.2.7** and - `setPost(new Post())` in **4.2.7 only** (fixed in https://hibernate.atlassian.net/browse/HHH-6484). With `FetchType.LAZY` neither `setPost(null)` nor `setPost(new Post())` triggers the orphan removal though (either in 4.2.6 or 4.2.7). – VH-NZZ Nov 29 '13 at 15:08

1 Answers1

2

Okay, the issue you refer to relates to a cascading delete when you have set the relationship to a new instance. You are setting to null so it is not really the same.

I tested your code (i.e. setting Post to null) under Hibernate 4.1.8 and it works as expected with the Post entry being deleted. I tested setting the Post to a new instance for an existing Point and the delete was not triggered which is consistent with the issue you refer to.

I then tested under 4.2.7 and the delete was fired for both cases so the issue you refer to is indeed fixed in 4.2.7.

Update:

I don't see why the Fetch hint would affect a persist operation however I have tried with it in place and the results were as before.

Alan Hay
  • 22,665
  • 4
  • 56
  • 110
  • See my EDIT above. JPA defaults the FetchType of OneToOne relationships to EAGER (LAZY otherwise). In my case, **with FetchType.LAZY**, the code snippet fails to remove the orphaned Post entity. This is as much true for 4.2.6 as for 4.2.7. The 6484 fix does correct the orphan removal when setting of a new instance (instead of just `null`), but this will also fail in 4.2.7 for FetchType.LAZY. – VH-NZZ Nov 29 '13 at 14:57
  • @AlanHay: in that case, Hibernate shouldn't have any problem in making the association lazy-loaded. The problem is when the foreign key is in the other table, or when the PK is also the FK, because in that case, it can't say from the data in the row if there is an associated entity or not. When the FK is in the table, there's no problem, since a null FK means that the association is null, and vice-versa. – JB Nizet Nov 29 '13 at 16:13
  • Yes you are quite right. In this case association can be lazy. Anway we are all looking at some non-existant issue it would seem. – Alan Hay Nov 29 '13 at 16:25
  • @AlanHay: Having read about it, I now understand the `optional=false/true` and Proxy issue. However, why would Hibernate issue a SELECT statement that does not fetch the Post entity in the LAZY case with (`optional=true`)? As for the "nonexistant issue": I tried the snippet again (`setPost(null)`) with version 4.2.7 and still no DELETE statement is issued. As I want the relationship to be optional=true, I suppose that the short answer is to leave the fetch mode to `EAGER`. But I am still not convinced that everything is behaving as it should in the `LAZY` case. – VH-NZZ Nov 29 '13 at 17:31
  • @okiharaherbst: I can confirm that with Hibernate 4.2.15 `orphanRemoval` does still does not work in the `LAZY` case. – Stefan Haberl Oct 03 '14 at 14:57
  • @StefanHaberl Thanks. You'd need to use a 4.3.x version. – VH-NZZ Dec 17 '14 at 11:11