在Google App Engine上使用JPA加载子实体

时间:2010-05-15 21:52:32

标签: java google-app-engine jpa persistence google-cloud-datastore

我们无法在Google App Engine上保留子实体后加载它们。我确信他们正在保存,因为我可以在数据存储区中看到它们。例如,如果我有以下两个实体。

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
}

我可以使用以下内容保存父母和孩子:

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

然而,当我尝试加载父项然后尝试访问子项(我知道GAE延迟加载)时,我没有得到子记录。

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

我在教程之后看过教程,到目前为止还没有任何工作。我正在使用SDK的1.3.3.1版。我已经看到了各种博客甚至App Engine论坛上提到的问题,但答案总是与JDO相关。我做错了什么或有其他人遇到过这个问题并为JPA解决了吗?

3 个答案:

答案 0 :(得分:2)

不要关闭实体管理器并调用子属性,这不是空的。只有在实体经理处于打开状态时,懒惰才会找到孩子。

答案 1 :(得分:1)

之前我遇到过同样的问题,尽管这似乎是一个奇怪的奇怪答案,但对我来说没有任何作用,直到我改变了

@OneToMany(mappedBy="parent", cascade=CascadeType.ALL)

@OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)

试试看,让我知道

答案 2 :(得分:0)

尝试在@OneToMany注释上添加mappedBy,如下所示:

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

另外,您应该在@ManyToOne注释中添加以下内容:

@ManyToOne(fetch = FetchType.LAZY)

此外,我发现使用Google Key和KeyFactory类很有用,因为您可以在创建子键时显式设置父级。

this.key = KeyFactory.createKey(parentKey, getClass().getSimpleName(), name);