Hibernate EntityManager.merge()导致创建新实体而不是更新现有实体

时间:2011-02-20 10:49:37

标签: hibernate jpa-2.0

我有以下(部分)层次结构:

@MappedSuperclass
public abstract class PersistentEntity {
    @Id
    @GeneratedValue(generator="system-uuid")
    @Type(type = "pg-uuid")
    public UUID getId() {
        return id;
    }
}

@Entity @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING) public abstract class AbstractCredential extends PersistentEntity { //content }

@Entity @DiscriminatorValue("Standard") @PrimaryKeyJoinColumn(name = "ID") public class StandardCredential extends AbstractCredential { //hashcode and quals here, by full data }

AbstractCredential是一个实体而不是@MappedSuperclass,因此我可以通过id从中进行选择,并获得相关的“具体”类。我的问题是,如果我用现有实例的id创建一个新的(分离的)实例,然后将该分离的实例传递给merge,hibernate会创建一个新的实体(意味着它会生成一个新的id,并覆盖我的id字段)新创建的实例)。 根据我的理解,hibernate应该用我的分离实例中的值覆盖现有实例中的所有字段。

我做错了什么?

1 个答案:

答案 0 :(得分:4)

可能是错的,但我认为分离的 new 是实体生命周期中的两种不同状态。分离的实体已在会话中从数据库加载,但会话已关闭。但是,在这种情况下,Hibernate应该知道实体已经存在于数据库中,并在稍后合并实体时相应地更新值。使用关键字 new 创建的实体也不会发生同样的情况,即使@ Id值相同也是如此。

This图清楚地表明,New / Transient-state中的实体与Detached(JPA)不同。 Here的实体状态的Hibernate(3.5)手册条目。我还检查了“Java Persistence with JPA”和“Spring persistence with Hibernate”-books,两者都类似地解释了实体状态和转换(分离的实体必须持久化到/从数据库中获取然后从持久化上下文/会话中分离出来变得超然)。遗憾的是,我无法找到任何提及如何通过 new 创建新对象并手动为其分配ID的情况下合并应该如何操作,这让我相信合并不应该以这种方式使用。不过,可能是错的。

相关问题