JDO in AppEngine: keep the original entity when de

2019-07-20 21:00发布

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?

3条回答
姐就是有狂的资本
2楼-- · 2019-07-20 21:52

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.

查看更多
ら.Afraid
3楼-- · 2019-07-20 21:55

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.

查看更多
淡お忘
4楼-- · 2019-07-20 21:57

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 always dependent, 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 using collections of keys or using foreign 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 use batch fetch to get child objects, in case of foreign keys, I use simple queries with where 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.

查看更多
登录 后发表回答