我在使用 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/