JDO /重复条目异常

时间:2012-03-08 15:16:05

标签: java mysql persistence jdo datanucleus

将对象保存到数据库时,我得到MySQLIntegrityConstraintViolationException。我知道这个错误意味着什么,但我不能解决它。

错误: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 org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3baac1b5

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

2 个答案:

答案 0 :(得分:1)

我不确定将分离的JDO与瞬态JDO联系起来是犹太的。 ORM没有简单的方法可以知道关系是现有的JDO。

如果它真的在同一个代码路径中,我会关联持久化实例:

c.addStudypath(dbStudypath);

否则我会在关联它之前makePersistent(detachedStudypath)(假设你的类是@Detachable)

答案 1 :(得分:1)

您可以通过调用JDOHelper.getObjectState(obj)轻松检查对象的状态。我强烈建议你,你的对象处于TRANSIENT状态而不是DETACHED状态,可能是因为你没有声明你的类是可拆卸的。