2012-03-08 3 views
0

데이터베이스에 개체를 저장할 때 MySQLIntegrityConstraintViolationException이 표시됩니다. 이 오류의 의미를 알지만 해결할 수는 없습니다.JDO/중복 항목 예외

오류 : Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '12345' for key 'PRIMARY'

는 기본적으로, 데이터베이스에 코스 객체를 저장할. 각 코스 오브젝트는 여러 개의 스터드 패스 오브젝트를 가질 수 있으며, 이는 여러 코스 오브젝트의 일부가 될 수 있습니다.

PersistenceManager pm = pmf.getPersistenceManager(); 
Transaction tx = pm.currentTransaction(); 

try { 
    tx.begin(); 
    Query query = pm.newQuery(Studypath.class,"studypathID == paramStudypathID"); 
    query.declareParameters("Integer paramStudypathID"); 
    query.setUnique(true); 
    Studypath dbStudypath = (Studypath)query.execute(12345); 

    Studypath detachedStudypath = null; 
    if (dbStudypath != null) { 
     detachedStudypath = (Studypath)pm.detachCopy(dbStudypath); 
    } else { 
     Studypath newStudypath = new Studypath(); 
     // ... 
     pm.makePersistent(newStudypath); 
     detachedStudypath = (Studypath)pm.detachCopy(newStudypath); 
    } 

    tx.commit(); 

    // now I want to add this detached studypath to my newly created course 
    Course c = new Course(); 
    c.addStudypath(detachedStudypath); 

    tx.begin(); 
    pm.makePersistent(c); // <== error 
    tx.commit(); 
} 
catch (Exception e) 
{ 
    //... handle exceptions 
} 
finally 
{ 
    if (tx.isActive()) 
    { 
     // Error occurred so rollback the transaction 
     tx.rollback(); 
    } 
    pm.close(); 
} 

Course.java

@PersistenceCabable 
public class Course { 
    // ... 

    @Persistent 
    private Set<Studypath> studypaths; 
} 

Studypath.java

@PersistenceCabable 
public class Studypath { 
    // ... 

    @Persistent 
    @PrimaryKey 
    private Integer studypathID; 
} 

는 내가 부족 명백한 실수가 있습니까? 미리 감사드립니다!

업데이트 (로그) :

DEBUG [DataNucleus.Datastore.Native] - SELECT 'Courses.Studypath' AS NUCLEUS_TYPE, ... FROM `STUDYPATH` `A0` WHERE `A0`.`STUDYPATHID` = <12345> // this one already exists 
DEBUG [DataNucleus.Datastore.Retrieve] - Execution Time = 0 ms 
DEBUG [DataNucleus.Datastore.Retrieve] - Retrieving PreparedStatement for connection "jdbc:mysql://127.0.0.1/database, UserName=user, MySQL-AB JDBC Driver" 

DEBUG [DataNucleus.Datastore.Native] - SELECT 'Courses.Course' AS NUCLEUS_TYPE, ... FROM `COURSE` `A0` WHERE `A0`.`COURSEID` = <1111> // there is no such course, thus it gets created 
DEBUG [DataNucleus.Datastore.Retrieve] - Execution Time = 1 ms 
DEBUG [DataNucleus.Datastore.Retrieve] - Retrieving PreparedStatement for connection "jdbc:mysql://127.0.0.1/database, UserName=user, MySQL-AB JDBC Driver" 
DEBUG [DataNucleus.Datastore.Native] - INSERT INTO `COURSE` (...,`COURSEID`) VALUES (...,<1111>) 
DEBUG [DataNucleus.Datastore.Persist] - Execution Time = 1 ms (number of rows = 1) 
DEBUG [DataNucleus.Datastore.Retrieve] - Closing PreparedStatement [email protected]b5 

DEBUG [DataNucleus.Datastore.Persist] - The requested statement "INSERT INTO `STUDYPATH` (...) VALUES (...)" has been made batchable 
DEBUG [DataNucleus.Datastore.Persist] - Batch has been added to statement "INSERT INTO `STUDYPATH` (...) VALUES (...)" for processing (batch size = 1) 
DEBUG [DataNucleus.Datastore.Persist] - Adding statement "INSERT INTO `STUDYPATH` (...) VALUES (...)" to the current batch (new batch size = 2) 
DEBUG [DataNucleus.Datastore.Persist] - Batch has been added to statement "INSERT INTO `STUDYPATH` (...) VALUES (...)" for processing (batch size = 2) 
DEBUG [DataNucleus.Datastore.Native] - BATCH [INSERT INTO `STUDYPATH` (...,`STUDYPATHID`) VALUES (...,<12345>); INSERT INTO `STUDYPATH` (...,`STUDYPATHID`) VALUES (<54321>)] 
ERROR [DataNucleus.Datastore] - Exception thrown 
+0

로그를 읽지 못했습니다. 그것은 당신에게 객체 상태를 알려주고, 당신이 persist를 호출 할 때 무슨 일이 일어나는지를 알려줍니다. 나는 개인적으로 그것을보고 끈기의 과정을 이해할 것이다 – DataNucleus

+0

의견을 주셔서 감사합니다, 방금 출력으로 내 질문을 업데이 트했습니다. 문제는 일괄 업데이트입니다. Studypath가 이미 존재하기 때문에 발생하지 않아야합니다. – tilo

+0

로그의 대부분을 생략하고 (예 : 수명주기) 어떤 일이 발생하는지 보지 마십시오 (일부 SQL의 최종 결과 제외) – DataNucleus

답변

1

나는 그것이 과도 하나에 분리 JDO를 연결하는 정결 확실하지 않다. ORM이 관계가 기존 JDO인지 쉽게 알 수있는 방법은 없습니다.

는 동일한 코드 경로에 정말 있다면, 나는 영속 인스턴스에 연결할 것 :

c.addStudypath(dbStudypath); 

를 그렇지 않으면 나는 그것을 연관 전에 makePersistent (detachedStudypath는)

+0

분리 된 것을 쉽게 알 수 있습니다. 그 이유 때문에 우리가 바이트 코드를 향상시킨 것입니다 .-) – DataNucleus

1

(클래스가 @Detachable입니다 가정) 것 JDOHelper.getObjectState (obj)를 호출하면 (자), 오브젝트 상태를 간단하게 체크 할 수 있습니다. 나는 당신의 객체가 TRANSIENT 상태가 아니라 DETACHED 상태임을 당신에게 강력히 추천한다. 당신이 당신의 클래스를 분리 가능하다고 선언했기 때문일 것이다.