我有一个非常简单的JAP-Entity,没有任何其他类的链接:
@Entity
@IdClass(TimestampNameAndGroupIdentity.class)
public class TechFitMainClassHistory extends JPABase {
@Id
@Basic
protected Date timestamp;
@Id
@Basic
protected String type_name;
@Id
@Basic
protected String group_name;
@Basic
protected int count;
...
与IdClass:
public class TimestampNameAndGroupIdentity implements Serializable {
private static final long serialVersionUID = 1L;
public Date timestamp;
public String type_name;
public String group_name;
...
在测试中,我尝试将其合并两次:
em.merge(new TechFitMainClassHistory(date, "com.test.Main", "java", 2));
em.merge(new TechFitMainClassHistory(date, "com.test.Main", "java", 2));
我收到以下错误
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: Violation of PRIMARY KEY constraint 'PK__TechFitM__D91CE761E4A3725C'. Cannot insert duplicate key in object 'dbo.TechFitMainClassHistory'. The duplicate key value is (PROCESS_TYPE_MAIN, 2015-09-03 00:00:00.0000000, com.ruxit.Main). {prepstmnt 261650860 INSERT INTO TechFitMainClassHistory (group_name, timestamp, type_name, count) VALUES (?, ?, ?, ?)} [code=2627, state=23000]
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:219)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:207)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$1200(LoggingConnectionDecorator.java:59)
at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.executeBatch(LoggingConnectionDecorator.java:1215)
at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.executeBatch(DelegatingPreparedStatement.java:250)
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement.executeBatch(JDBCStoreManager.java:1810)
at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.executeBatch(BatchingPreparedStatementManagerImpl.java:364)
at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushBatch(BatchingPreparedStatementManagerImpl.java:189)
... 39 more
有两种情况没有出现错误: *如果我在电话之间提交 *如果在调用之前对象已存在
这只是简化的测试用例,实际的应用程序做了类似的事情,我希望根据merge()方法的描述来工作。
那么为什么我会收到此错误?我希望合并多次工作,或者这是OpenJPA中的错误/限制?
答案 0 :(得分:0)
合并的预期行为是:
因此,您在测试用例中所期望的行为应该有效,除非两个合并调用都不是在相同的持久化上下文中进行的(两次调用之间的提交修复了您的错误导致认为是这种情况)
然而,在并发上下文中,您将重现此问题,因为两个实体都属于两个不同的等级持久化上下文,第二个要刷新将触发pk违规