1

我在带有 Oracle 的 WebLogic 10.0.x 上使用 OpenJPA (JPA 1.0)。我已经定义了一个 OneToMany 关系如下:

@Entity
public class Compound implements Serializable {
    ...
    @OneToMany(mappedBy="compound", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    private List<Submission> submissions = new ArrayList<Submission>();
    ...
}

@Entity
public class Submission implements Serializable {
    ...
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.REFRESH)
    @JoinColumn(name="compoundId")
    private Compound compound;
    ...
}

当我删除一个复合实体时,所有子提交实体也应该被删除。这作为一般规则起作用,除了我在这些表上设置了外键约束:

ALTER TABLE SUBMISSION
ADD CONSTRAINT FK_SUBMISSION_COMPOUND
    FOREIGN KEY (COMPOUNDID)
    REFERENCES COMPOUND(COMPOUNDID);

现在,当我尝试删除 Compound 实体时,遇到以下异常:

ORA-02292: integrity constraint (HELC.FK_SUBMISSION_COMPOUND) violated - child record found {prepstmnt 3740 DELETE FROM Compound WHERE compoundId = ? [params=(long) 10384]} [code=2292, state=23000]"

上述异常意味着 Open JPA 在将删除级联到子实体之前尝试删除父级。我已经通过谷歌阅读了一些关于这个异常的文章,可以追溯到 2006 年。但是,最近的文章表明这​​个 bug 已经修复了?

http://mail-archives.apache.org/mod_mbox/openjpa-dev/200609.mbox/%3C14156901.1158019042738.JavaMail.jira@brutus%3E

https://issues.apache.org/jira/browse/OPENJPA-235

谁能建议为什么这不起作用以及我能做些什么?我不愿意手动删除子实体,特别是因为这是我的架构中不太复杂的关系之一,我为此使用的任何解决方案都需要在其他地方应用。

谢谢杰

4

1 回答 1

1

当我删除一个复合实体时,所有子提交实体也应该被删除。这作为一般规则起作用,除了我在这些表上设置了外键约束:

如果您可以更改外键约束,那么就数据库而言应该可以解决问题。我不确定 OpenJPA 在这里的表现如何。

ALTER TABLE SUBMISSION
ADD CONSTRAINT FK_SUBMISSION_COMPOUND
    FOREIGN KEY (COMPOUNDID)
    REFERENCES COMPOUND(COMPOUNDID)
    ON DELETE CASCADE;

一件事-如上所述,这是Weblogic 10.0.x。我怀疑我们使用的是捆绑版本的 OpenJPA / Kodo,它可能已经很老了......

我自己的感觉是你提到的错误应该已经被这个版本修复了,但它也是 a) 时间足够接近以至于它可能没有被修复,并且 b) 可能是一个足够大的问题,我认为你应该花一些时间时间验证版本和修复。(实际上,我刚刚注意到OpenJPA 1.0 是在 2007 年 8 月发布的。这比我想象的要早得多,这使得您更有可能没有修复错误。)

如果您无法修改数据库(因为它是一个遗留系统,显然不打算让客户端依赖级联删除),并且如果您的版本中未修复该错误,则您必须管理顺序SQL 语句自己。

手动管理 SQL 语句的负担——这是 OpenJPA 应该您做的事情之一——可能足以让管理人员升级 OpenJPA 或更新数据库中的外键约束。

我真的希望你得到比这个更好的答案。

于 2012-05-22T11:19:42.977 回答