views:

62

answers:

1

I am not able to get child entities to load once they are persisted on Google App Engine. I am certain that they are saving because I can see them in the datastore. For example if I have the following two entities.

public class Parent implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String key;
    @OneToMany(cascade=CascadeType.ALL)
    private List<Child> children = new ArrayList<Child>();

    //getters and setters
}

public class Child implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String key;
    private String name;
    @ManyToOne
    private Parent parent;
    //getters and setters
}

I can save the parent and a child just fine using the following:

Parent parent = new Parent();
Child child = new Child();
child.setName("Child Object");
parent.getChildren().add(child);
em.persist(parent);

However when I try to load the parent and then try to access the children (I know GAE lazy loads) I do not get the child records.

//parent already successfully loaded
parent.getChildren.size(); // this returns 0

I've looked at tutorial after tutorial and nothing has worked so far. I'm using version 1.3.3.1 of the SDK. I've seen the problem mentioned on various blogs and even the App Engine forums but the answer is always JDO related. Am I doing something wrong or has anyone else had this problem and solved it for JPA?

A: 

Try adding mappedBy on the @OneToMany annotation like below:

@OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
private List<Child> children = new ArrayList<Child>();

Also, you should add below to the @ManyToOne annotation:

@ManyToOne(fetch = FetchType.LAZY)

Also, I find it useful to use the Google Key and KeyFactory classes because then you can explicitly set the parent when creating the child key.

this.key = KeyFactory.createKey(parentKey, getClass().getSimpleName(), name);
Taylor Leese
Also, I have working examples of using JPA parent/child relationships in my jappstart project: http://jappstart.com
Taylor Leese