Issue Details (XML | Word | Printable)

Key: NUCRDBMS-549
Type: Bug Bug
Status: Closed Closed
Resolution: Won't Fix
Priority: Major Major
Assignee: Unassigned
Reporter: Daniel Baldes
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Store RDBMS

Removal of collection element deletes element despite not being marked "dependent"

Created: 25/Jul/11 02:57 PM   Updated: 03/Oct/11 07:38 AM   Resolved: 29/Aug/11 04:36 PM
Component/s: None
Affects Version/s: 3.0.0.m6
Fix Version/s: None

File Attachments: 1. GZip Archive datanucleus.testcase.tar.gz (2 kB)


Forum Thread URL: http://www.datanucleus.org/servlet/forum/viewthread_thread,6758


 Description  « Hide
I got a collection property where the collection elements are not marked as "dependent-element", but the mapping field is not nullable. When I remove such elements from that collection, they are (unexpectedly) automatically deleted.

This is caused by FkSetStore.checkRemovalOfElementShouldDelete(ownerSM) returning true, code comment is "Field is not dependent, and is not nullable so we just delete the elements".

Expected behavior would be that I can remove the element and add it to another collection. If I did not add it to another collection, I'd get an exception during flush() or commit().

Test case follows.

Sort Order: Ascending order - Click to sort in descending order
Daniel Baldes added a comment - 25/Jul/11 02:57 PM
In the attached test case, in Test.java line 29, an exception is thrown:

javax.jdo.JDOUserException: Cannot read fields from a deleted object

because the element was deleted during remove() in line 27.

Daniel Baldes added a comment - 10/Aug/11 02:37 PM
Update: the mentioned code from FkSetStore was moved to RDBMSFkSetStore in 3.0.0 (final).

The problem still exists, and it is even more complicated than I thought; it seems that we cannot change this easily, as the removal of the element is flushed to the datastore right away. I had the misconception that this would only happen during flush() or commit(). Of course, the element cannot be stored when the foreign key field is not nullable.

I'd appreciate if we could discuss this in the linked forum thread. (See my initial question: how to "move" such an element from one owner to another; this seems to be impossible, yet it is a use case for me).

Andy Jefferson added a comment - 18/Aug/11 10:41 AM
Try using optimistic txns since that delays all operations til commit/flush, hence you have the chance to perform multiple operations before they get sent to the datastore.

Daniel Baldes added a comment - 29/Aug/11 11:19 AM
Using optimistic transactions does not seem to help on its own. The operation does not fail immediately as with normal transactions, but it fails on commit (the DeleteRequests are still there).

As a workaround, I'll declare fields NULL-able in metadata, then it should work with optimistic transactions.

I think this is a "won't fix", unless you got a better idea...

Daniel Baldes added a comment - 29/Aug/11 11:31 AM - edited
Declaring fields NULLable in metadata is not sufficient, as DN actually sends the field update to NULL and then another update to the current value. Isn't this a bit inefficient? Should the object not be updated just once, to its state at the time of commit or flush?

Andy Jefferson added a comment - 29/Aug/11 04:36 PM
Marked as Won't Fix, as requested.

When running that simple case, apart from the fact that
1. it is not a valid testcase,
2. it doesn't initialise "elements" hence NPEs,
3. it doesn't set both sides of a bidirectional relation.
... with optimistic transactions it works fine for me (HSQLDB).
SQL statements sent are
INSERT INTO OWNER (OWNER_ID,ID) VALUES (<1>,<0>)
INSERT INTO OWNER (OWNER_ID,ID) VALUES (<2>,<0>)
INSERT INTO "ELEMENT" (ELEMENT_ID,ID,OWNER_OWNER_ID_OID) VALUES (<1>,<0>,<2>)
SELECT 'org.datanucleus.test.Element' AS NUCLEUS_TYPE,A0.ID,A0.ELEMENT_ID FROM "ELEMENT" A0 WHERE A0.OWNER_OWNER_ID_OID = <1>

Behaviour without delayed flush is as expected to me. Only way you can do such swapping is to delay all operations until a flush

Daniel Baldes added a comment - 29/Aug/11 04:42 PM
The latter ("only way") does not work for me as described in my previous comment. DN either executes the delete request before trying to update, or it updates the owner field to NULL and then to the new owner, depending on metadata-declared NULLability.

Daniel Baldes added a comment - 29/Aug/11 05:06 PM
Well, now I found the last paragraph in the problem reporting guide which describes your preferred test case format.