我有以下(部分)层次结构:
@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应该用我的分离实例中的值覆盖现有实例中的所有字段。
我做错了什么?
答案 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的情况下合并应该如何操作,这让我相信合并不应该以这种方式使用。不过,可能是错的。