3

我们的系统中有两个实体,如下所示:

  • Invoice:[InvoiceID, OrgID] 是表示为 bean 的主键,并使用@IdClass注解与 Invoice 关联

  • WorkflowStates:是使用注解WorkflowStateId定义的主键列。@Id

在这两个实体中,ID 字段(InvoiceID、WorkflowStateId)是使用 DB 序列自动生成的。

在对新创建的 Invoice 实例调用 persist 时,当我们将 InvoiceID 设置为 时-1,实例会被持久化并且 ID 会正确生成。

但是,当在 WorkflowStateID 设置为的新创建的 WorkflowStates 实例上调用 persist 时-1persist()调用会引发异常:

 org.hibernate.PersistentObjectException: detached entity passed to persist: <Entity Class>

我在搜索中找不到太多,如果persist()方法对具有单列作为 PK 的实体和具有复合 PK 的实体的工作方式有任何差异。有人知道更多吗?

4

2 回答 2

1

我认为你得到了这个例外,因为你为你的持久性分配了一个 id,同时你在你的映射中指定了 id 是自动生成的。

当您执行persist()时,休眠假设该对象已经存在于您的数据库中(基于您的对象已经具有Id的事实)......但事实并非如此。这就是你得到例外的原因。

所以,我建议你删除所有的 setId(-1)。(在持久化对象之前保持 id 为空)

编辑

每当实体具有 Single Id 列或 Compound Id 时,hibernate 检测实体是否持久的方式存在一些差异。(我知道是因为我查看了代码,但在文档中没有找到任何内容)。

我建议你设置一个断点DefaultPersistEventListener.onPersist,看看发生了什么。或者启用休眠调试日志并对其进行分析。

于 2012-12-21T12:36:31.317 回答
0

我的猜测是这@IdClass会有所不同,因为实际上发票没有“id 列”。它具有复合键,因此不会生成 InvoiceId。您作为 invoiceId 提供的值将在持久操作期间使用(在本例中为 -1)。因此,发票的“Id”将是您提供的 2 个值(invoiceId 和 orgId)的组合,hibernate 不会用生成的值覆盖它们,它只会使用给定的值。

我不知道代码,所以我很难说更多。如果您可以提供代码示例,那将有很大帮助。

于 2012-12-21T13:46:18.683 回答