将对象保存到数据库时,我得到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
答案 0 :(得分:1)
我不确定将分离的JDO与瞬态JDO联系起来是犹太的。 ORM没有简单的方法可以知道关系是现有的JDO。
如果它真的在同一个代码路径中,我会关联持久化实例:
c.addStudypath(dbStudypath);
否则我会在关联它之前makePersistent(detachedStudypath)(假设你的类是@Detachable)
答案 1 :(得分:1)
您可以通过调用JDOHelper.getObjectState(obj)轻松检查对象的状态。我强烈建议你,你的对象处于TRANSIENT状态而不是DETACHED状态,可能是因为你没有声明你的类是可拆卸的。