【问题标题】:Hibernate/JPA: em.merge( new MyEntity(id) ) returns proxy without collectionsHibernate/JPA:em.merge(new MyEntity(id)) 返回没有集合的代理
【发布时间】:2012-07-22 01:26:37
【问题描述】:

休眠 EntityManager 3.4.0 或 3.6.10

MyEntity {
    @Id   // NOT @GeneratedValue
    long cislo;

    @OneToMany( ... )
    List<MyItem> items = new ArrayList();


    public MyEntity( long cislo ) { this.cislo = cislo; }
    ...
}

然后,在 DAO 中:

MyEntity ent = new MyEntity( id );
ent.addItem( new Item( ... ) );
ent.addItem( new Item( ... ) );
ent = em.merge( ent );

1) 为什么我需要使用merge(),而不是persist(),它会抱怨实体已分离?是手动设置ID的原因吗?

2) 为什么这个合并返回一个没有集合集的代理?

3) 最重要的是:我怎样才能从merge()获得完全初始化的实体?
除了在成员集合上设置EAGER
我可以使用原始对象,但我很好奇它是否可能。 我也可以查询实体,但这似乎是在浪费资源。

【问题讨论】:

    标签: hibernate jpa merge


    【解决方案1】:

    1.) 你为什么在这里使用“Session.merge()”?合并通常用于将分离的实体实例重新附加到 Hibernate/JPA 会话 - 这通常发生在您在会话之外重用实体实例(例如,在视图层中)并且您希望将任何更改传播到这些实例到使用 Session 的数据库。

    2.) Hibernate 文档说“如果给定实例未保存,请保存它的副本并将其作为新的持久实例返回。” 在您的情况下,由于您尝试“合并”一个全新的实例,Hibernate 将首先将其保存到数据库中,然后将其作为新的实体实例重新获取。返回代理的原因是因为 Hibernate 默认延迟加载任何 Collection。为了确保集合的getter 方法返回实际集合。 Hibernate 创建一个代理。

    3.) 我很好奇你为什么不在这里使用 Session.save()。

    【讨论】:

    • 也许你错过了它是 JPA 与 Hibernate 作为底层 impl,而不是纯 Hibernate。
    • @OndraŽižka - 我的评论仍然有效。 merge() 方法,无论是从 JPA 的 EntityManager 还是 Hibernate 的 Session 中使用,都以相同的方式工作。
    • 无意冒犯,但它会导致 1) 无效,因为没有其他东西可以使用,3) 因为没有 save()。感谢您的回答 2)。关于3),似乎我只需要习惯merge()的这种行为......
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多