I have two objects a user and a role which I make persistant using JDO and googles app engine. The two datatypes are related to each other as unowned many to many relationship. I tried to model that much as in the gae-tutorial desribed as sets holding the key of the corresponding object. By the time I create my objects, those keys are null. So in order to get some keys generated I make those objects persistant. After that, I add the refering keys to those objects. However those keys are not getting stored in the end.
Beside setting the keys, I also manipulate some other attributes (after makePersistent). Those changes later are reflected in the datastore. However, all the key changes I make after makePersistent, do no开发者_如何学运维t make it to the datastore. If I set those keys before makePersistent, they get stored as they should. However, that is no solution, as at least one object must logically receive the key refrence after it was made persistant.
Below some sample code, to explain the issue.
What is good practice to store those keys?
Persistable Role class
public class Role {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key Role_id;
@Persistent
private Set<Key> Users = new HashSet<Key>();
...
}
Persistable User class
public class User {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key User_id;
@Persistent
private String EMail = null;
@Persistent
private Set<Key> Roles = new HashSet<Key>();
...
}
Code extract which creates 1 Role and 1 User and tries to set the key-references on both sides. They keys changs don't end up in the datastore. However, the change on the email address is written to the data store. ...
PersistenceManager pm = PMF.get().getPersistenceManager();
Role GlobalAdmin = new Role();
User Daniel = new User();
try {
pm.makePersistent(GlobalAdmin);
pm.makePersistent(Daniel);
} catch (Exception e){
System.out.println("Storing failed: " + e.getMessage());
}
GlobalAdmin.addUser(Daniel.getUser_id());
Daniel.addRole(GlobalAdmin.getRole_id());
Daniel.setEMail("a@b.com");
pm.close();
...
I think you should read the documentation from datanucleus. This will explain the solution you currently have.
http://www.datanucleus.org/products/accessplatform_1_1/jdo/attach_detach.html
JDO provides an interface to the persistence of objects. JDO 1.0 doesn't provide a way of taking an object that was just persisted and just work on it and update the persisted object later. The user has to copy the fields manually and copy them back to the persisted object later. JDO 2.0 introduces a new way of handling this situation, by detaching an object from the persistence graph, allowing it to be worked on in the users application. It can then be attached to the persistence graph later.
I found one solution to my problem. When I want to write those keys, I have to detach those objects and make them persistent again later. Neither I understand why I have to do that nor if there would be something more elegant. However, it proofs to work.
So first of all those classes must be detechable:
@PersistenceCapable(detachable = "true")
public class User {
...
After making the objects persistant, I detach them, set my keys and reatch those objects to the store...
...
pm.makePersistent(GlobalAdmin);
pm.makePersistent(Daniel);
pm.detachCopy(GlobalAdmin);
pm.detachCopy(Daniel);
GlobalAdmin.addUser(Daniel.getUser_id());
Daniel.addRole(GlobalAdmin.getRole_id());
pm.makePersistent(GlobalAdmin);
pm.makePersistent(Daniel);
...
精彩评论