【问题标题】:PostgreSQL JPA cascade partially workingPostgreSQL JPA 级联部分工作
【发布时间】:2012-08-08 12:26:33
【问题描述】:

同样,我们可能有一个非常简单的问题; 我们的数据库如下所示:

CREATE TABLE Question (
    idQuestion SERIAL,
    questionContent VARCHAR,

    CONSTRAINT Question_idQuestion_PK PRIMARY KEY (idQuestion),
);

CREATE TABLE Answer (
    idAnswer SERIAL,
    answerContent VARCHAR,
    idQuestion INTEGER,

    CONSTRAINT Answer_idAnswer_PK PRIMARY KEY (idAnswer),
    CONSTRAINT Answer_idQuestion_FK FOREIGN KEY (idQuestion) REFERENCES Question(idQuestion),
);

所以一个问题有很多答案。 在 Netbeans 7.1.2 生成的实体中,我们有字段:

@OneToMany(mappedBy = "idquestion", orphanRemoval=true, cascade= CascadeType.ALL, fetch= FetchType.EAGER)
private Collection<Answer> answerCollection;

如您所见,我已经添加了所有可能的孤儿删除和级联指令,用于级联删除集合。它工作正常,但有一段时间:

只有在我们应用程序的先前“实例”中创建问题和连接的答案时,您才能删除它们。如果我首先创建一个新问题甚至一个答案,然后直接删除它,我们会收到如下错误:

root cause

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: update or delete on table "question" violates foreign key constraint "answer_idquestion_fk" on table "answer"
  Detail: Key (idquestion)=(30) is still referenced from table "answer".
Error Code: 0
Call: DELETE FROM question WHERE ((idquestion = ?) AND (version = ?))
    bind => [2 parameters bound]
Query: DeleteObjectQuery(com.accenture.androidwebapp.entities.Question[ idquestion=30 ])
root cause

org.postgresql.util.PSQLException: ERROR: update or delete on table "question" violates foreign key constraint "answer_idquestion_fk" on table "answer"
  Detail: Key (idquestion)=(30) is still referenced from table "answer".

如果我重新启动(重建、重新部署)它正在工作的应用程序.. 为什么?谢谢!

【问题讨论】:

  • 如果你flush()实体管理器然后删除,那么它成功了吗?
  • 没有帮助。我猜它的集合没有被重新加载或什么的。我还在自己寻找:)
  • 无论我做什么都无济于事......而且问题只发生在同一个“运行”中。我可以从应用程序注销,关闭浏览器,添加更多问题,无论如何 - 删除运行中创建的任何问题,导致错误:/重新部署及其工作......
  • 您是在使用扩展的持久性上下文,还是长时间保持 EntityTransaction 打开?我想知道您的应用程序的“运行”是否使用单个巨型事务并将所有内容都附加到 EntityManager,而不是使用短控制事务。如果它是同一个应用程序实例中的新 EntityManager 或者它是否是新的应用程序实例,这真的无关紧要。长 EntityTransactions 不会立即导致您的问题,但导致性能问题并有丢失未提交数据的风险,并且可能会在重启后解释差异。
  • 另外,请出示您对Answer的映射。

标签: database hibernate postgresql jpa entity


【解决方案1】:

尝试将 EclipseLink @PrivateOwned 扩展注释添加到您的集合映射中。

至于在您重新启动应用程序之前无法删除的问题,我想到了两件事:

  • 您可能正在使用非常长的 EntityManager 会话,其中所有内容都与 EnitityManager 保持连接。如果是这种情况,那么重新启动强制更改 EntityManager 会话会有所帮助。完成会话后,请考虑通过调用 EntityManager.close() 来使用较短的 EntityManager 会话。当您想修改它时,使用分离的实体和EntityManager.merge() 状态。

  • 二级缓存(如果有)将通过重新部署来清除。尝试禁用二级缓存,看看是否有帮助。

【讨论】:

  • 真正有帮助的是@Overriding remove 方法如下:@Override public void remove(Question entity) { em.refresh(entity); super.remove(entity); } 所以我猜这是EM会话的问题。我们如何解决这个问题?有什么我们应该调查的吗?
  • @Atais 覆盖 what 删除方法?一些 DAO 或门面?它通常是做什么的?至于会议:提供的信息量几乎是不可能的。您对应用的配置或操作、会话的管理方式等只字未提。
  • 它在门面。好吧,要解释的太多了,但我们之前已经在这里制作了我们的应用程序的图片:stackoverflow.com/questions/11687033/… 有问题的是图表。
  • @Atais 好的,您正在为外观使用无状态会话 bean (EJB3.1?)。您是否使用 JTA 数据源,所以容器会为您进行事务管理?或者您正在使用带有 JPA 托管事务的 jdbc 数据源?我打赌后者,你无意中得到了很长的会话。考虑 JTA 和容器管理的 tx,它在使用无状态 EJB 时效果很好。
  • 我们使用 jdbc 和 jpa.... 我们可以对应用程序做一些危害较小的更改吗?我们真的不想改变整个数据库连接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
相关资源
最近更新 更多