GAE JPA @OneToMany orphanRemoval + Cascade无法按预期工作

时间:2016-01-09 23:13:19

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

我在使用Appengine + JPA + Jersey方面遇到了一些麻烦,我不会使用这种组合,但我被大学逼迫(项目截止日期10.01.16 18:00 GMT + 1)

当他们的“Schule”被删除时,我想删除所有“Lehrer”,并对“Schule”进行修改。当“Lehrer”被删除时,“Schule”应该仍然保持不变。这是我的课程:

@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”Stay并且现在有一个无效的“Schule”引用。

当将“Lehrer”的@ManyToOne设置为Cascade.All时,关联的“Schule”会在删除“Lehrer”后删除,以便它以这种方式工作,但反之亦然。

我做错了什么?

感谢您的帮助 - Flo

更新,看起来在添加带有Lehrer.schule的“Lehrer”作为他的“Schule”对象时,“Schule”中的Set为空。

通过手动删除像goofiw建议的cild项目来解决方法。

@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();
}

1 个答案:

答案 0 :(得分:1)

当删除文档时,可能会在Lehrer表中删除对Schule的引用,从而导致Schule列的null。当您在Lehrer表中查找要删除的Schule行时,它不再存在。当你删除Schule的文档时,你可以用Lehrer中的Schule null删除任何行。