我在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());
答案 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旁边的其他属性,这是最初填充的唯一内容(延迟提取)。