Bug 380 : Failed TestManyToManySaveTwice - Unique index or primary key violation
Priority 
High
Reported Version 
 
Logged By 
Rob
Status 
Fixed
Fixed Version 
2.7.5
Assigned To 
 
Product 
Ebean - core
Duplicate Of 
 
Created 
02/03/2012
Updated 
02/03/2012
Type 
Bug
 
Attachments 
No attachments

javax.persistence.PersistenceException: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_75 ON PUBLIC.SP_CAR_CAR_WHEELS(CAR, WHEEL)"; SQL statement:
insert into sp_car_car_wheels (car, wheel) values (?, ?) [23001-153]
at com.avaje.ebeaninternal.server.persist.ExeUpdateSql.execute(ExeUpdateSql.java:95)
at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeSqlUpdate(DefaultPersistExecute.java:144)
at com.avaje.ebeaninternal.server.core.PersistRequestUpdateSql.executeNow(PersistRequestUpdateSql.java:63)
at com.avaje.ebeaninternal.server.core.PersistRequest.executeStatement(PersistRequest.java:93)
at com.avaje.ebeaninternal.server.core.PersistRequestUpdateSql.executeOrQueue(PersistRequestUpdateSql.java:68)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.executeSqlUpdate(DefaultPersister.java:166)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveAssocManyIntersection(DefaultPersister.java:1071)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveMany(DefaultPersister.java:801)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveAssocMany(DefaultPersister.java:711)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.update(DefaultPersister.java:447)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveEnhanced(DefaultPersister.java:343)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.saveRecurse(DefaultPersister.java:315)
at com.avaje.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:282)
at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1653)
at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1643)
at com.avaje.ebean.Ebean.save(Ebean.java:536)
at com.avaje.tests.sp.TestManyToManySaveTwice.testInsertCarTwice(TestManyToManySaveTwice.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_75 ON PUBLIC.SP_CAR_CAR_WHEELS(CAR, WHEEL)"; SQL statement:
insert into sp_car_car_wheels (car, wheel) values (?, ?) [23001-153]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
at org.h2.message.DbException.get(DbException.java:167)
at org.h2.message.DbException.get(DbException.java:144)
at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:80)
at org.h2.index.TreeIndex.add(TreeIndex.java:57)
at org.h2.table.RegularTable.addRow(RegularTable.java:127)
at org.h2.command.dml.Insert.insertRows(Insert.java:126)
at org.h2.command.dml.Insert.update(Insert.java:86)
at org.h2.command.CommandContainer.update(CommandContainer.java:69)
at org.h2.command.Command.executeUpdate(Command.java:212)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:143)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:129)
at com.avaje.ebeaninternal.server.lib.sql.ExtendedPreparedStatement.executeUpdate(ExtendedPreparedStatement.java:164)
at com.avaje.ebeaninternal.server.persist.ExeUpdateSql.execute(ExeUpdateSql.java:87)
... 35 more

 
Rob 02 Mar 07:53
The issue

So the issue here is that the Many collection was a plain LinkedHashSet so when we save it the second time we should delete all the matching intersection rows first because we can't detect the 'additions' and 'deletions'.

Rob 02 Mar 07:54
Fixed in HEAD

Fixed in HEAD.

Default Persister line 1022.

woResponse

Upload a file