在持续GAE后将子实体添加到父级

时间:2012-11-29 00:09:28

标签: java google-app-engine jpa

我有一个父实体客户端。该客户可以访问该网站并创建约会。这意味着约会是在客户端对象的另一个时间创建的。

我的问题是:如何将子对象添加到已经持久化的父对象? 如果调用下面示例中的函数addData1(),则会创建一个约会表并添加一个条目。当调用函数addData2()时,这不会发生。

在关闭实体管理器后更新持久化对象时,这是否也是如此?

@Entity
public class Client{
    @Id
    private String name;
    @OneToMany(cascade = CascadeType.ALL)
    private Set<Appointment> appointments;
}

@Entity
public class Appointment{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key id;
}

// This works
public function addData1(){
    EntityManager em = EMF.get().createEntityManager();
    Client client = new Client(name);
    for(Appointment a  : newAppointments)
        client.addAppointment(a);
    em.persist(client);
    em.close();
}

// This doesn't work.
public function addData2(){
    EntityManager em = EMF.get().createEntityManager();
    Client client = new Client(name);
    em.persist(client);
    em.close();
    for(Appointment a  : newAppointments)
        client.addAppointment(a);
}

1 个答案:

答案 0 :(得分:1)

public function addData1(){
    EntityManager em = EMF.get().createEntityManager();
    Client client = new Client(name);
    for(Appointment a  : newAppointments)
        client.addAppointment(a);
    em.persist(client);
    em.close();
}

此功能有效,因为您可以保留所有对象。

// This doesn't work.
public function addData2(){
    EntityManager em = EMF.get().createEntityManager();
    Client client = new Client(name);
    em.persist(client);
    em.close();    <--- You persist client with no appointment
    for(Appointment a  : newAppointments)
        client.addAppointment(a);   <-- those entitys are detached entity ( not persisted)
}

此函数不会因为您尝试使用分离的实体持久保存对象

你应该得到这样的例外:

Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.test.Appointment

如果您想避免此异常,可以尝试这种方法:

public void addData2(List<Appointment> newAppointments){
    Client client = new Client();
    client.setName("name1");
    entityManager.persist(client);
    for(Appointment a  : newAppointments)
        client.addAppointment(a);
    entityManager.merge(client);
    entityManager.close();
}

BTW,尝试使用名称作为Id

进行无效