将子集合复制到另一个对象

时间:2010-06-04 06:16:35

标签: java hibernate jpa glassfish

我在Part和Params之间有一对多的关系(“Part”有很多“Params”。

我正试图做一些像这样天真的事情:

Part sourcePart = em.find(Part.class, partIdSource);
Part destPart = em.find(Part.class, partIdDest);

Collection<Param> paramListSource = sourcePart.getParamList();

destPart.setParamList(paramListSource);

基本上我想将所有参数从sourcePart复制到destPart。希望持久性提供程序将自动在Param表/实体中设置正确的外键。

上述代码显然不起作用。

有没有简单的方法,或者我必须创建一个新的集合,然后添加每个Param(创建新的Param,设置属性等)?

修改

我尝试先拆分该实体,就像在另一个线程中推荐的那样,但我得到一个异常(org.hibernate.PersistentObjectException:传递给persist的分离实体:shared.entity.Param)。

Part sourcePart = em.find(Part.class, partIdSource);
// force eager loading...
((List)sourcePart.getParamList()).get(0);

Part destPart = em.find(Part.class, partIdDest);

// detach entity
org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();
session.evict(sourcePart);

//causes exception "detached entity passed to persist"
destPart.setParamList(sourcePart.getParamList());

3 个答案:

答案 0 :(得分:2)

  

基本上我想将所有参数从sourcePart复制到destPart。希望持久性提供程序将自动在Param表/实体中设置正确的外键。

如果你想采用“逐出方式”,让你的实体 Detached 足够 ,你需要“取消”Id属性所以您的实体再次成为 New (持久化它们必须导致SQL INSERT)。在伪代码中:

MyObject ob = session.get(idOfExisting);
hibernate.evict(ob);
ob.setId(null);
hibernate.save(ob);

但我发现这很脏。我将迭代列表中的项目并使用复制构造函数(不复制Id属性)来创建新列表,然后在目标对象上设置副本(这将是提供程序不可知的)。

答案 1 :(得分:1)

也许你可以在Param中实现clone()方法。然后你可以做paramListSource.clone()

答案 2 :(得分:1)

我很确定你得到的实际上不是Param实例,而是实现Param接口的代理对象,所以你可能需要创建新的Param对象并复制属性。另外,不要将它们从会话中分离出来,因为如果它们是代理,它们将无法获取Id旁边的其他属性,这是最初填充的唯一内容(延迟提取)。