I have defined an unowned relationship using JDO 3.0 syntax:
@Persistent
@Unowned
private Set<Role> roles;
I have several predefined roles which should be assigned to users. I use following code for adding/removing roles to users:
roles.add(roleEntity);
roles.remove(roleEntity);
The problem is that removing like this also removes the original entity from the datastore but I just want to remove the reference. I know I could store only Keys inside the parent entity which would solve the problem, but is there a better solution? Using this "natural" syntax?
I'm seeing the same thing. Granted I'm a newbie to all this, but even with @Unowned if I remove an item from an ArrayList which it was on when first persisted the object is deleted from the data store. Seems pretty much the same as before I added @Unowned. So the only way I can transfer the object from the ArrayList of one object to that of another is to find it first before calling remove(), then make a deep copy, then I can remove() and put the copy on the other list. Not at all natural.
As I've struggled with this for ages, let me share the solution that finaly works for me. Who knows, it might help someone else as the documentations are not very helpful.
To remove a child from the parent's collection without deleting the original persitent object you need to:
1) Use a Set not a List
At first I used only Lists, A) for the ordering and B) because Sets + RequestFactory ValueProxy doesn't work. So be sure to use EntityProxy
2) Anotate this set with @Unowned
They didn't put this annotation in their Unowned one-to-many example: https://developers.google.com/appengine/docs/java/datastore/jdo/relationships#Unowned_Relationships But without it you get an exception when you try to add an element to your set (can't change parent)
3) Not sure it's necessary but I've also annotated with @Element(dependent = "false")
Hope this will help some people. If not, well, no harm done.
I guess this question deserves a real final answer.
The described behavior was caused by a bug in JDO and it should be fixed by now. See http://code.google.com/p/datanucleus-appengine/issues/detail?id=290 for more details. Also notice, that
owned
relationships are alwaysdependent
, no matter what the documentation says.Unfortunately, it was fixed after I had moved back to JDO 2.0. In JDO 2.0, I implement
unowned
relationships usingcollections of keys
or usingforeign keys
. And actually it's not a bad solution so I don't plan to try JDO 3.0 again. For a collection of keys I usebatch fetch
to get child objects, in case of foreign keys, I use simple queries withwhere
statement. Sometimes it's better to use the first solution, sometimes the second one. It's all covered by a clean API anyway, so the final code is simple and "natural". (I wish this approach was described directly in the documentation so we don't have to learn it the hard way.)The important thing is that in both cases I can destroy the relationship without deleting original entities. It's a true
unowned
relationship.