java - GAE JPA @OneToMany orphanRemoval + Cascade 未按预期工作

标签 java google-app-engine jpa one-to-many

我在使用 Appengine + JPA + Jersey 时遇到了一些麻烦,我不会使用这个组合,但我是被大学强制的(项目截止日期 10.01.16 18:00 GMT+1)

当“Schule”被删除时,我想删除所有引用“Schule”的“Lehrer”。当“Lehrer”被移除时,“Schule”应该仍然保持不变。这是我的类(class):

<小时/>
@Entity
@XmlAccessorType(XmlAccessType.NONE)
public class Lehrer {
    @Id
    @XmlElement
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    @XmlElement
    private String vorname;
    @XmlElement
    private String nachname;

    @Transient
    @XmlElement
    private String passwort;

    private String hash;

    private String salt;

    @XmlElement
    @Unowned
    @ManyToOne(optional = false)
    private Schule schule;

    ..getter&setters..

}
<小时/>
@Entity
@XmlAccessorType(XmlAccessType.NONE)
public class Schule {
    @Id
    @XmlElement
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    @XmlElement
    private String name;

    @OneToMany(cascade = CascadeType.ALL,mappedBy = "schule", orphanRemoval = true)
    private Set<Lehrer> Lehrerliste;

    @OneToMany(cascade = CascadeType.ALL,mappedBy = "schule", orphanRemoval = true)
    private Set<Klasse> Klassenliste;

    ...getter&setter...
}
<小时/>

以及删除“Schule”的代码。

@DELETE
@Path("/id/{id}")
public Response deleteSchule(@PathParam("id") long id) {

    EntityManager em = EMF.get();
    Schule GesuchterSchule = em.find(Schule.class, KeyFactory.createKey("Schule", id));

    if (GesuchterSchule != null) {

        System.out.println("remove " + GesuchterSchule + "\n");

        em.remove(GesuchterSchule);

        em.close();
        return Response.status(Status.NO_CONTENT).build();
    }
    em.close();
    System.out.println("remove faild for id: " + id + "\n");
    return Response.status(Status.NOT_FOUND).build();
}
<小时/>

现在我的问题是,一旦删除“Schule”,关联的“Lehrer”就会保留,现在有一个无效的“Schule”引用。

当将“Lehrer”的@ManyToOne设置为Cascade.All时,一旦删除“Lehrer”,关联的“Schule”就会被删除,因此它会以这种方式工作,但反之则不然。

我做错了什么?

感谢您的帮助 - 弗洛

<小时/>

更新,看起来当添加一个以 Lehrer.schule 作为他的“Schule”对象的“Lehrer”时,“Schule”中的 Set 为 null。

<小时/>

解决方法是手动删除 cild 项目,如建议的 goofiw。

@DELETE
@Path("/id/{id}")
@SuppressWarnings("unchecked")
public Response deleteSchule(@PathParam("id") long id) {

    EntityManager em = EMF.get();
    Schule GesuchterSchule = em.find(Schule.class, KeyFactory.createKey("Schule", id));

    Query query = em.createQuery("SELECT e FROM Lehrer e WHERE e.schule = :s");
    query.setParameter("s", GesuchterSchule);
    List<Lehrer> list = (List<Lehrer>) query.getResultList();
    em.getTransaction().begin();
    for (Lehrer lehrer : list) {
        em.remove(lehrer);
    }
    em.getTransaction().commit();

    if (GesuchterSchule != null) {
        System.out.println("remove " + GesuchterSchule + "\n");
        em.getTransaction().begin();
        em.remove(GesuchterSchule);
        em.getTransaction().commit();
        em.close();
        return Response.status(Status.NO_CONTENT).build();
    }
    em.close();
    System.out.println("remove faild for id: " + id + "\n");
    return Response.status(Status.NOT_FOUND).build();
}

最佳答案

可能发生的情况是,当删除文档时,Lehrer 表中对 Schule 的引用也会被删除,从而导致 Schule 列为 null。当您在 Lehrer 表中查找要删除的 Schule 行时,它已不存在。当您删除 Schule 文档时,您可以做什么,删除 Lehrer 中 Schule 为 null 的所有行。

关于java - GAE JPA @OneToMany orphanRemoval + Cascade 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34700032/

相关文章:

java - 如何使用 sql 创建嵌套选择?

java - 使用 persistence.xml 时将 Hibernate 4.0 与 Tomcat 7 结合使用时出现 JndiException

python - enable-app-engine-project 有点乱

Java数组打印出奇怪的数字和文本

java - CXF JAXRS - 如何将日期作为 QueryParam 传递

java - 在类路径资源 [spring/database/DataSource.xml] 中定义了名称为 'dataSource' 的无效 bean 定义

java - 使用 blobstore 解析 gaej 中的 csv 文件

java - 如何使用 Long id 查询实体的 java appengine 数据存储 VIEWER

java - 使用hibernate处理大量数据

java - 锁屏而不关闭