Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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.sql.SQLIntegrityConstraintViolationException_Java_Jpa - Fatal编程技术网

更新实体时发生java.sql.SQLIntegrityConstraintViolationException

更新实体时发生java.sql.SQLIntegrityConstraintViolationException,java,jpa,Java,Jpa,我是JPA新手,我遇到了以下问题,可能是因为对级联和关联的理解不够? 我有两个实体,它们是双向的一对一-多对一关联: @Entity public class TestRun implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;

我是JPA新手,我遇到了以下问题,可能是因为对级联和关联的理解不够? 我有两个实体,它们是双向的一对一-多对一关联:

@Entity
public class TestRun implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Long getId() {
        return id;
    }

    public TestRun(){

    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne(optional=false, cascade={CascadeType.PERSIST, CascadeType.MERGE})
    private Test performedTest;

    public Test getPerformedTest() {
        return performedTest;
    }

    public void setPerformedTest(Test performedTest) {
        this.performedTest = performedTest;
    }
    .....

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof TestRun)) {
            return false;
        }
        TestRun other = (TestRun) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "TestRun[ id=" + id + " ]";
    }
}
以及:

当createTestRun处理新的测试(插入)时,测试对象与测试运行一样被正确地持久化。但是当测试已经存在时,JPA(在我的例子中是EclipseLink)无论如何都会尝试执行插入:

....
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL110705102925930' defined on 'TEST'.
Error Code: -1
Call: INSERT INTO TEST (ID, NAME) VALUES (?, ?)
幕后发生了什么?这个问题是否与测试的AppearSonterRuns属性有关?为什么JPA不理解DB中已经存在测试(毕竟,id属性是在find操作期间设置的,equals()使用此值来决定两个测试是否相等..) 非常感谢你的帮助!:)


PS:你知道有一本很好的教程/书详细解释了这些概念吗?

首先,你应该检查整个
createTestRun
方法(找到测试,必要时创建测试,然后创建
TestRun
实例并将其持久化)是否在单个事务中运行

您的newestrun方法应该初始化关系的两侧,这是双向的。开发人员有责任保持实体图的一致性。因此,它应该做到:

public static TestRun newTestRun(Test test){
    TestRun run = new TestRun();
    run.setPerformedTest(test);
    test.getAppearsOnTestRuns().add(run);
    return run;
}

你能给我们看看EntityFactory.newTestRun(testPerformed)的代码吗?嗨!我刚做完!:)我认为:从DB中检索到的Test-s在ejb.find()返回后被解除跟踪,因此应该从同一事务中手动合并,然后保存新的TestRun对象?它们不应该分离。整个createTestRun方法应该在单个事务中执行。事务应该用于原子功能更改,而不是用于原子查询或数据库更新。问题是,我必须在不同的时间构建TestRun对象。。假设createTestRun(字符串名)返回它创建的TestRun对象,并且第二次,另一个方法调用ejb.persist(TestRun)。。我是否必须在EJB公共void persist(TestRun TestRun){TestRun.setPerformedTest(em.merge(TestRun.getPerformedTest());em.persist(TestRun);}中显式执行://Method,还是有更好/更简单的方法?谢谢我不明白。另一个线程将有另一个TestRun实例。有什么问题吗?您还没有显示EntityFactory.newTestRun(testPerformed)的代码。
....
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL110705102925930' defined on 'TEST'.
Error Code: -1
Call: INSERT INTO TEST (ID, NAME) VALUES (?, ?)
public static TestRun newTestRun(Test test){
    TestRun run = new TestRun();
    run.setPerformedTest(test);
    test.getAppearsOnTestRuns().add(run);
    return run;
}