Java JDO/重复条目异常
将对象保存到数据库时,我会得到一个Java JDO/重复条目异常,java,mysql,persistence,jdo,datanucleus,Java,Mysql,Persistence,Jdo,Datanucleus,将对象保存到数据库时,我会得到一个MySQLIntegrityConstraintViolationException。我知道这个错误意味着什么,但我无法解决它 错误:原因:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:键“PRIMARY”的重复条目“12345” 基本上,我想将课程对象保存到数据库中。每个课程对象可能有多个studypath对象,这些对象又可以是多个课程对象的一部分 Pers
MySQLIntegrityConstraintViolationException
。我知道这个错误意味着什么,但我无法解决它
错误:原因:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:键“PRIMARY”的重复条目“12345”
基本上,我想将课程对象保存到数据库中。每个课程对象可能有多个studypath对象,这些对象又可以是多个课程对象的一部分
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();
}
我有什么明显的错误遗漏吗?提前谢谢
更新(日志):
DEBUG[DataNucleus.Datastore.Native]-选择'Courses.Studypath'作为NUCLEUS\u类型。。。来自'STUDYPATH``A0',其中'A0`.'STUDYPATHID`=//这个已经存在
调试[DataNucleus.Datastore.Retrieve]-执行时间=0毫秒
调试[DataNucleus.Datastore.Retrieve]-检索连接的PreparedStatement“jdbc:mysql://127.0.0.1/database,UserName=user,MySQL AB JDBC驱动程序“
调试[DataNucleus.Datastore.Native]-选择'Courses.Course'作为NUCLEUS\u类型。。。从'COURSE``A0'开始,其中'A0`.'COURSEID`=//没有这样的课程,因此它被创建
调试[DataNucleus.Datastore.Retrieve]-执行时间=1毫秒
调试[DataNucleus.Datastore.Retrieve]-检索连接的PreparedStatement“jdbc:mysql://127.0.0.1/database,UserName=user,MySQL AB JDBC驱动程序“
调试[DataNucleus.Datastore.Native]-插入'COURSE'(…,'COURSEID')值(…,)
调试[DataNucleus.Datastore.Persist]-执行时间=1毫秒(行数=1)
调试[DataNucleus.Datastore.Retrieve]-关闭PreparedStatement org.DataNucleus.store.rdbms。ParamLoggingPreparedStatement@3baac1b5
DEBUG[DataNucleus.Datastore.Persist]-请求的语句“INSERT INTO`STUDYPATH`(…)VALUES(…)”已可批处理
调试[DataNucleus.Datastore.Persist]-已将批添加到语句“INSERT INTO`STUDYPATH`(…)VALUES(…)”中进行处理(批大小=1)
调试[DataNucleus.Datastore.Persist]-将语句“INSERT INTO`STUDYPATH`(…)值(…)”添加到当前批(新批大小=2)
调试[DataNucleus.Datastore.Persist]-已将批添加到语句“INSERT INTO`STUDYPATH`(…)VALUES(…)”中进行处理(批大小=2)
调试[DataNucleus.Datastore.Native]-批处理[插入'STUDYPATH`(…,'STUDYPATHID`)值(…,);插入'STUDYPATH`(…,'STUDYPATHID`)值()]
错误[DataNucleus.Datastore]-引发异常
我不确定将一个分离的JDO与一个临时JDO相关联是否符合犹太教。ORM不容易知道关系是一个现有的JDO
如果它真的在同一个代码路径中,我会关联持久实例:
c.addStudypath(dbStudypath);
否则,我会在关联对象(假设您的类是@detacheable)之前将其设置为persistent(detachedStudypath)您可以通过调用JDOHelper.getObjectState(obj)轻松检查对象的状态。我强烈建议您的对象处于瞬态而不是分离状态,这可能是因为您尚未将类声明为可分离的。缺少一个日志的读取。这将告诉您对象状态,以及调用persist时发生的情况。我个人会看一下并理解坚持的过程谢谢你的评论,我刚刚用输出更新了我的问题。问题是批处理更新,这不应该发生,因为Studypath已经存在。您省略了大部分日志(如生命周期),因此看不到正在发生什么(某些SQL的最终结果除外)。有一种简单的方法可以知道它已分离。。。这就是为什么我们用字节码来增强它们;-)
@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
c.addStudypath(dbStudypath);