gpt4 book ai didi

java - 为什么 eclipselink/jpa 在我不要求的情况下尝试保留实体?

转载 作者:行者123 更新时间:2023-12-01 16:01:38 30 4
gpt4 key购买 nike

我试图在事务中持久化 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说:

If the entity is already managed, the persist operation is ignored, although the persist operation will cascade to related entities that have the cascade element set to PERSIST or ALL in the relationship annotation.

最佳答案

弗兰克是正确的。您没有读取表达式,因此当您调用 persist on Meaning 时,当它引用现有表达式时,它们会被分离,这会导致事务失败。调用 merge 会起作用,或者您可以删除 exps 关系上的级联持久化,因为您似乎直接持久化了新的表达式,无论如何它都不需要。

关于java - 为什么 eclipselink/jpa 在我不要求的情况下尝试保留实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3723365/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com