views:

83

answers:

2

Hi all,

I have a hibernate model with two classes, let's say A and B. B has a many-to-one reference to A.

I query a single A and a single B object. These are detached from the Session and they get processed somewhere/used else. The B.A property is a lazy proxy. Sometime later A and B both need to be deleted. I create a new Session and call .delete(A) and .delete(B).

Deleting A is ok but then deleting B causes the following exception

Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.xxx.hibernate.objects.B.A
    at org.hibernate.engine.Nullability.checkNullability(Nullability.java:95) [hibernate3.jar:na]
    at org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:272) [hibernate3.jar:na]
    at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:163) [hibernate3.jar:na]
    at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:74) [hibernate3.jar:na]
    at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:794) [hibernate3.jar:na]
    at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:772) [hibernate3.jar:na]

Diggin in the code it looks as tho during the deletion a nullability check is done, and because A was deleted first, deletion of B fails the null check. It thinks it's A reference is "null" even tho the B object I pass in it is set to not-null. Looks like it does some lookup in the interal Session state and finds the deleted A instance.

Anyone know how I can work round this? I would prefer not to rely on the ordering of the deletion if possible, unless deleting A before B is fundamentally wrong for some reason I'm not seeing.

I'm also not entirely sure why a null check is required on a delete TBH.

Appreciate any suggestions.

+1  A: 

I think you have to delete all the "children" before you delete the "parent". I realise you don't want to be at the mercy of the order of deletions, but I don't think there's any other way around this.

EDIT: just an idea, but have a look at what is actually arriving in the database at each step of the delete. If Hibernate is setup to create a DELETE command using all the columns of the table, including the foreign key linking to A, then the DELETE command won't find anything if it's looking for a NULL value of the A key.

davek
Good idea but sadly it is just doing a delete on the id and versionNo which is what I'd expect.
Mike Q
Forced to conclude that order is important, I guess hibernate is trying to enforce the fk constraints before the delete hits the DB.
Mike Q
+1  A: 

Deleting A will set the reference to it in B to null which is forbidden by the schema. An alternative to changing the order of deletions would be to add a reverse one-to-many collection in B, with cascaded deletes. Only the deletion of A would than be needed.

Maurice Perry