【发布时间】:2010-09-16 02:47:14
【问题描述】:
我试图在一个事务中持久化 3 个实体 (exp,def,meng),然后再持久化另外 2 个 (def', meng'),其中 meng' 与 exp 相关。
但是,当我试图坚持 meng 时,eclipselink/jpa2 被告知:
Call: INSERT INTO EXPRESSION (EXPRESSION, GENDER) VALUES (?, ?)
bind => [exp, null]
这将抛出一个表达式,因为它已经被插入并且它是一个键。 所以显然坚持实体 meng' 包括更新 exp 本身会以某种方式使 eclipselink 认为我要求坚持一个新的 exp。
这是测试:
@Test
public void testInsertWords() throws MultipleMengsException, Exception{
final List<String[]> mengsWithSharedExp = new LinkedList<String[]>();
mengsWithSharedExp.add(mengsList.get(3));
mengsWithSharedExp.add(mengsList.get(4));
insertWords(mengsWithSharedExp, null, mengsDB);
}
这是有问题的代码:
public void insertWords(EnumMap<Input, MemoEntity> input) throws MultipleMengsException {
Expression def = (Expression) input.get(Input.definition);
Expression exp = (Expression) input.get(Input.expression);
beginTransaction();
persistIfNew(def);
persistIfNew(exp);
persistNewMeng(null, exp, def);
commitTransaction();
}
private void persistNewMeng(final MUser usr, Expression exp, final Expression def) throws RuntimeException {
final Meaning meng = new Meaning(usr, exp, def);
if (!persistIfNew(meng)) {
throw new RuntimeException("Meng ." + meng.toString() + " was expected to be new.");
}
if (usr != null) {
usr.addMeng(meng);
}
}
public <Entity> boolean persistIfNew(final Entity entity) {
final Object key = emf.getPersistenceUnitUtil().getIdentifier(entity);
if (em.find(entity.getClass(), emf.getPersistenceUnitUtil().getIdentifier(entity)) != null) {
return false;
}
em.persist(entity);
return true;
}
您可以从here 签出 Maven 源代码(进行测试)。
这是预期的行为吗?如果是这样,为什么?还有最重要的,怎么解决?
好像
@ManyToMany(cascade=CascadeType.ALL)
private Set<Expression> exps;
意义是罪魁祸首,虽然我不明白为什么会这样。 documentation 说:
如果实体已被管理,则忽略持久化操作,尽管持久化操作将级联到在关系注释中将级联元素设置为 PERSIST 或 ALL 的相关实体。
【问题讨论】:
标签: java orm eclipselink jpa-2.0