Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么eclipselink/jpa试图持久化一个实体,而我不';你不要求吗?_Java_Orm_Eclipselink_Jpa 2.0 - Fatal编程技术网

Java 为什么eclipselink/jpa试图持久化一个实体,而我不';你不要求吗?

Java 为什么eclipselink/jpa试图持久化一个实体,而我不';你不要求吗?,java,orm,eclipselink,jpa-2.0,Java,Orm,Eclipselink,Jpa 2.0,我试图在一个事务中持久化3个实体(exp,def,meng),然后持久化另外2个实体(def',meng'),其中meng'与exp相关 然而,当我试图坚持孟日食/jpa2时,有人告诉我: Call: INSERT INTO EXPRESSION (EXPRESSION, GENDER) VALUES (?, ?) bind => [exp, null] 这将抛出一个expression,因为它已经被插入并且是一个键。 因此,显然,坚持包含更新exp本身的实体会让eclipsel

我试图在一个事务中持久化3个实体(exp,def,meng),然后持久化另外2个实体(def',meng'),其中meng'与exp相关

然而,当我试图坚持孟日食/jpa2时,有人告诉我:

Call: INSERT INTO EXPRESSION (EXPRESSION, GENDER) VALUES (?, ?)
    bind => [exp, null]
这将抛出一个expression,因为它已经被插入并且是一个键。 因此,显然,坚持包含更新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 testInsertWords()引发乘法异常,异常{
最终列表mengsWithSharedExp=新建LinkedList();
mengsWithSharedExp.add(mengsList.get(3));
mengsWithSharedExp.add(mengsList.get(4));
插入字(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;
    }
public void insertWords(EnumMap输入)引发乘法异常{
表达式def=(表达式)input.get(input.definition);
表达式exp=(表达式)input.get(input.Expression);
beginTransaction();
新的(def);
新的(实验);
persistenewmeng(null、exp、def);
提交交易();
}
私有void persistenewmeng(最终MUser usr、表达式exp、最终表达式def)抛出RuntimeException{
最终含义=新含义(usr、exp、def);
如果(!persistIfNew(meng)){
抛出新的RuntimeException(“Meng.+Meng.toString()+”应该是新的。”);
}
如果(usr!=null){
usr.addMeng(meng);
}
}
公共布尔persistIfNew(最终实体){
最终对象键=emf.getPersistenceUnitUtil().getIdentifier(实体);
if(em.find(entity.getClass(),emf.getPersistenceUnitUtil().getIdentifier(entity))!=null){
返回false;
}
em.persist(实体);
返回true;
}
您可以从中签出Maven源代码(要测试)

这是预期的行为吗?若然,原因为何?最重要的是,如何解决

看起来好像

@ManyToMany(cascade=CascadeType.ALL)
private Set<Expression> exps;
@ManyToMany(cascade=CascadeType.ALL)
私有集扩展;
意思是罪魁祸首,尽管我不明白为什么会这样。报告说:

如果实体已被管理,则将忽略持久化操作,尽管持久化操作将级联到相关实体,这些实体的级联元素在关系注释中设置为持久化或全部


您很可能会遇到:

[…]如果实体被分离[…]事务提交将失败

(与您引用的来源相同)

如果持久化引用已持久化实体的新实体,则必须使用“合并”而不是“持久化”。“合并”将保留新实体并更新现有实体


还要注意,合并操作将返回一个附加的数据图,该数据图必须用于同一持久性上下文中的进一步操作。

Frank是正确的。您没有读取表达式,因此当您调用persist on means时,当它引用现有表达式时,它们被分离,这会导致事务失败。调用merge将起作用,或者您可以删除exps关系上的cascade persist,因为您似乎可以直接持久化新表达式,而这是不需要的

所以这可以更精确:@manytomy(cascade={CascadeType.MERGE,CascadeType.REFRESH,CascadeType.REMOVE})。但是一旦我删除了一个表达式(在删除数据库中的所有mengs后,我发现表'EXPRESSION'上的DELETE违反了外键约束'MNNGXPRSSXSPSXPRSSN'。因此,如果从Means persist中删除所有级联注释属性,应该可以工作。看起来是这样,但不知何故,实体仍然潜伏在周围。事实上,当我删除所有的Means时,其中一个是不存在的(当我通过持有实体的级联操作进行删除时)。如果我确实尝试显式删除它,我会得到一个异常,即删除持有exp和MEG实体关系的表。为什么?