我遇到了 JPA 的删除问题,这是我的代码:
public deleteLine(int idLine) {
Line line = em.find(Line.class,idLine);
Header header = line.getHeader();
this.deleteLine(header,line);
}
public boolean deleteLine(Header header, Line line) {
try {
line.setIdArticle(null);
line.setDetail(DELETED_TAG);
line.setQuantity(0.0f);
em.merge(line);
header.getLineCollection().remove(line);
em.remove(line);
em.flush();
}
catch (Exception ex) {
LOG.log(Level.SEVERE, null, ex);
}
return true;
}
当我调用 deleteLine()
时,我以 idArticle
为 null
的数据库行结束,详细信息等于 DELETED_TAG
常量和 quantity
等于 0
。但是该行仍然存在,尽管 em.remove
。
我试图在删除之前添加一个 line.setHeader(null)
,但我得到了一个 ConstraintViolationException
,因为标题字段不能为 null
.
显然我做错了什么,但我不知道是什么。
有实体代码:
public class Header implements Serializable {
[...]
@OneToMany(cascade = CascadeType.ALL, mappedBy = "header")
private Collection<Line> lineCollection;
[...]
}
public class Line implements Serializable {
[...]
@JoinColumn(name = "header", referencedColumnName = "header")
@ManyToOne(optional = false)
private Header header;
[...]
}
我已经完成了通过 JPQL 删除行的测试(DELETE FROM Linea WHERE idLinea=?
),它有效地删除了行。但是,当 JPA 执行提交时,由于 JPA 完成的 INSERT
,该行重新出现。
有没有办法发现原因?显然,有一个生成插入的实体,但我要从标题中删除该行,所以我该怎么做才能弄清楚是什么触发了插入?
最佳答案
我想通了问题出在哪里:当用户删除一行时,我正在这样做
- 调用删除线
- 做一些计算并用结果更新标题
由于 jpa 的工作方式,对头字段的修改强制 jpa 跳过删除子项(因为级联所有)或重新插入它,因为实际上实体仍然存在并且 hibernate “行走”并重建父级- child 树。
对于面临同样问题的人,如果你想删除一个 child 并在删除后更新 parent ,我发现的正确方法是:
- 从父集合中移除子集合
- 更新标题
- 删除 child
对我来说,按照这个确切的顺序做事就解决了问题。
关于java - JPA 不删除数据库行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25365271/