tags:

views:

66

answers:

3

Collection.clear() will delete children whenever Session flushes.

What about OneToOne? Setting to null is not a correct way. No clear() method for OneToOne exists.

Table_A has a column (not its PK!) that OneToOne references Table_B.

I wonder if Hib works as expected in my case?

My Cascading options are set to "all,delete-orphan".

Table_A @OneToOne Table_B

Table_B @OneToMany Table_C

Now it looks like Table_A . getTable_B . getTable_C_Collection()

Suppose there are elements in Table_C collection.

What I expect from Hibernate: if I set Table_B link to null, then

all Table_C collection elements MUST BE DELETED.

It does not happen. They become ORPHANED !

+1  A: 

No, deleting parent will delete children if you have cascading turned on.

You need to send DELETE SQL to the database, and merely setting a reference to null won't do that.

duffymo
@duffymo But that's weird. You see: how we delete linked objects (children): Collection.clear(). And how to do this thing with OneToOne? I also need something like OneToOneLink.clear() and the only thing to do this as I see it is set reference to NULL.
EugeneP
+1  A: 

Have you tried "all-delete-orphan" instead of "all,delete-orphan"? The two are supposed to work the same, but there have been problems in the past where one has different behaviour from the other. Such issues are actually bugs, so if using one rather than the other does behave differently, be sure to open a bug.

You might also want to play with setting inverse='true' in your Hibernate mappings. From the documentation, and from this Stack Overflow Question, it looks like inverse=true is often the key to getting cascade deletes to work properly.

Jim Hurne
+1  A: 

Hibernate's support for cascading actions can be a bit quirky at times. If you find that you cannot get the desired behavior out-of-the-box, you can implement a Hibernate Interceptor or a Hibernate event listener. It's actually pretty easy to do ether, and the effort is worth it (your main code remains clean).

In this case, you probably want to implement a PostUpdateEventListener, or a PreUpdateEventListener.

Jim Hurne