Bean Mapping(Dozer)的Hibernate持久性问题

时间:2010-12-29 13:47:58

标签: java hibernate mapping dozer

我正在使用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的接口。有相应的FooImpl和BarImpl类,它们本质上只是没有注释的实体对象。

我要做的是构建一个新的FooImpl实例,并在设置了多个字段后保留它。新的Foo实例将其“bar”成员设置为来自数据库的现有Bar(运行时为BarEntity)(通过session.get(..)检索)。在FooImpl设置了所有属性之后,Apache Dozer用于在“域”对象FooImpl和Entity FooEntity之间进行映射。 Dozer在后台做的是实例化一个新的FooEntity并设置所有匹配的字段。 BarEntity也通过实例化进行克隆,并设置了FooEntity的“bar”成员。

发生这种情况后,将新的FooEntity对象传递给persist。抛出异常:

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注释来解决此问题,但是这限制了将来的用途,例如添加新Foo并附加了新的Bar。我在这里有一些解决方案吗?如果这个问题之前没有得到解决,我会感到惊讶,要么通过改变Dozer如何映射Foo的孩子或者Hibernate如何对一个独立的子实体作出反应。

2 个答案:

答案 0 :(得分:0)

你能看一下你是否有一个包含此事的交易?如果您发布的第二位代码没有包含任何事务,那么当您尝试保留时,BarEntity将与Hibernate会话分离,这将导致您提到的错误。

答案 1 :(得分:0)

我怀疑推土机的映射是罪魁祸首。尝试将属性copy-by-reference =“true”添加到FooImpl / FooEntity的属性栏。