我可以覆盖生成的ID吗?

时间:2010-11-08 16:41:13

标签: java oracle hibernate jpa

我正在使用JPA 1,Hibernate和Oracle 10.2.0,我的实体定义如下:

@Entity
@Table(name="TERMS")
public class Term implements Serializable {
    @Id
    @GenericGenerator(name = "generator", strategy = "guid", parameters = {})
    @GeneratedValue(generator = "generator")
    @Column(name="TERM_ID")
    private String termId;
}

我的情况是实体(和子实体)的XML表示将通过Web服务进入以更新/替换现有的。我的想法是删除旧的并从传入的XML重新创建它。

然而,当我的实体拥有现有ID时,持续存在似乎让Hibernate非常愤怒。那么这实际上是可能的,还是最好避免删除它们,只是尝试用合并来做?

来自休眠的愤怒:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.idbs.omics.catalog.entity.Term

由于

2 个答案:

答案 0 :(得分:2)

  

我的想法是删除旧的并从传入的XML重新创建它。但是,当我的实体拥有现有ID似乎让Hibernate非常生气时,继续执行..

实际上,你不能在它应该被生成的时候分配Id,至少不能在Hibernate中分配不会将实体视为 new 但是分离< / em>(JPA规范在这种情况下的确切规则有点模糊,但这就是Hibernate的行为方式,有关更多提示,请参阅5.1.4.5. Assigned identifiers)。

  

这实际上是可行的,还是最好避免删除它们,只是尝试用合并来做?

要使Web服务用例可以删除/插入,您必须:

  • 不指定id~或〜
  • 使用没有生成标识符的实体的特殊版本〜或〜
  • 使用bulk operations(?)

如果您实际更新已分离的实体,则可以使用merge(但请查看这些previous questions情况)。

哪种方法更好?我不知道,它认为这取决于你的需求。如果您要更新现有实体,后者似乎更自然。对于前者,您真的会获得“新”实体(包括乐观锁定列的新值)。根据流程的具体实施情况,性能也可能有所不同。而且,顺便说一句,并发性(仅提及它,我真的没有期待答案)?

答案 1 :(得分:0)

您可以使用EntityManager.merge保存实体的更新版本。请注意,这将返回另一个对象而不是传递给它的对象,因为它基本上从数据库中提取实体,从您传递的对象更新持久属性并保存持久对象。

有关此问题的详情,请参阅http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/