我正在使用 Hibernate 3,并且在持久化与现有分离实体有关联的新实体时遇到特定问题。解释这一点的最简单方法是通过代码示例。我有两个实体,FooEntity 和 BarEntity,其中一个 BarEntity 可以与许多 FooEntity 关联:
@Entity
public class FooEntity implements Foo{
@Id
private Long id;
@ManyToOne(targetEntity = BarEntity.class)
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@Cascade(value={CascadeType.ALL})
private Bar bar;
}
@Entity
public class BarEntity implements Bar{
@Id
private Long id;
@OneToMany(mappedBy = "bar", targetEntity = FooEntity.class)
private Set<Foo> foos;
}
Foo 和 Bar 是为各种字段松散定义 getter 的接口(interface)。有相应的 FooImpl 和 BarImpl 类,它们本质上只是没有注释的实体对象。
我想要做的是构造一个 FooImpl 的新实例,并在设置多个字段后将其持久化。新的 Foo 实例将其“bar”成员设置为来自数据库(通过 session.get(..) 检索)的现有 Bar(运行时为 BarEntity)。在 FooImpl 设置其所有属性后,Apache Dozer 用于在“域”对象 FooImpl 和实体 FooEntity 之间进行映射。 Dozer 在后台做的是实例化一个新的 FooEntity 并设置所有匹配的字段。 BarEntity 也通过实例化克隆并设置 FooEntity 的“bar”成员。
发生这种情况后,传递新的 FooEntity 对象以保持。这会引发异常:
org.hibernate.PersistentObjectException: detached entity passed to persist: com.company.entity.BarEntity
下面是代码中发生的步骤
FooImpl foo = new FooImpl();
//returns at runtime a persistent BarEntity through session.get()
Bar bar = BarService.getBar(1L);
foo.setBar(bar);
...
//This constructs a new instance of FooEntity, with a member 'bar' which itself is a new instance that is detached)
FooEntity entityToPersist = dozerMapper.map(foo, FooEntity.class);
...
session.persist(entityToPersist);
我已经能够通过删除或更改 @Cascade 注释来解决这个问题,但这限制了 future 的使用,例如添加一个新的 Foo 并且已经附加了一个新的 Bar。这里有我缺少的解决方案吗?如果这个问题以前没有在某个地方解决,我会感到惊讶,无论是通过改变 Dozer 映射 Foo 的 child 的方式还是 Hibernate 对分离的子实体的 react 。
最佳答案
我怀疑推土机映射是罪魁祸首。尝试将属性 copy-by-reference="true"添加到 FooImpl/FooEntity 的属性栏。
关于java - Bean 映射 (Dozer) 的 Hibernate 持久性问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4554652/