【问题标题】:Hibernate Persistence problems with Bean Mapping (Dozer)Bean Mapping (Dozer) 的 Hibernate Persistence 问题
【发布时间】:2010-12-29 13:47:57
【问题描述】:

我正在使用 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”成员设置为来自数据库(通过 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 注释来解决这个问题,但这限制了未来的使用,比如添加一个新的 Foo 已经附加了一个新的 Bar 。我在这里缺少一些解决方案吗?如果这个问题以前没有得到解决,我会感到惊讶,无论是通过改变 Dozer 如何映射 Foo 的子级或 Hibernate 如何对分离的子实体做出反应。

【问题讨论】:

    标签: java hibernate mapping dozer


    【解决方案1】:

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

    【讨论】:

    • 这似乎解决了我的特定问题。我认为我最终可能会为这种情况使用一个特殊的推土机映射,因为使用按引用复制会稀释我最初尝试的接口抽象类型。
    【解决方案2】:

    您能否看看您是否有围绕此的交易?如果您发布的第二段代码没有包含任何事务,那么在您尝试持久化时,BarEntity 将与 Hibernate Session 分离,这将导致您提到的错误。

    【讨论】:

    • 一切都发生在同一个事务中。这是通过 HibernateTransactionManager 和 Spring 注释控制的
    • 您是如何在 BarEntity 上实现 equals() 和 hashcode() 的?我认为如果 equals() 或 hashcode() 没有正确实现,休眠可能无法在其会话中找到 BarEntity。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 2020-11-14
    • 2013-06-25
    • 2011-06-28
    • 1970-01-01
    • 2016-11-27
    相关资源
    最近更新 更多