2015-08-31 19 views
5

tôi sử dụng OpenJPA 2.4.0 trên MySQLOptimisticLockException khi loại bỏ thực thể trong OpenJPA mySQL

Tôi có 3 bảng - meeting, location, meeting_location.

meeting_location là bảng tham gia, trong đó có 1 khóa ngoại là meeting và 2 đến location - main_location_idsecondary_location_id.

Tôi khởi tạo các bảng với các tham số sau và sau đó cố gắng xóa mục nhập khỏi bảng meeting.

id loc_name  
------ ------------ 
    0 location 0 
    1 location 1 
    2 location 2 
    3 location 3 
    4 location 4 
    5 location 5 
    6 location 6 
    7 location 7 
    8 location 8 
    9 location 9 


     id name  
------ ----------- 
    1 meeting 1 


      id meeting_id main_location_id secondary_location_id name  
------ ---------- ---------------- --------------------- -------- 
    1   1     4      9 (NULL) 
    2   1     2      7 (NULL) 
    3   1     0      5 (NULL) 
    4   1     3      8 (NULL) 
    5   1     1      6 (NULL) 

Khi tôi cố gắng gọi

entityManager.remove(meeting) 

tôi nhận được một org.apache.openjpa.persistence.OptimisticLockException:

org.apache.openjpa.persistence.OptimisticLockException: Optimistic locking errors were detected when flushing to the data store. 
The following objects may have been concurrently modified in another transaction: 
[com.test.StackOverflowQuestionTest.MeetingLocation-3, 
com.test.StackOverflowQuestionTest.MeetingLocation-5, 
com.test.StackOverflowQuestionTest.MeetingLocation-1, 
com.test.StackOverflowQuestionTest.MeetingLocation-2, 
com.test.StackOverflowQuestionTest.MeetingLocation-4] 

Dưới đây là danh sách kiểm tra đầy đủ:

SQL:

/*Table structure for table `meeting` */ 
DROP TABLE IF EXISTS `meeting`; 
CREATE TABLE `meeting` (
    `id`       INT(16) NOT NULL, 
    `name`    VARCHAR(128), 
    PRIMARY KEY (`id`) 

) 
    ENGINE =INNODB 
    DEFAULT CHARSET =utf8; 


     /*Table structure for table `location` */ 
DROP TABLE IF EXISTS `location`; 
CREATE TABLE `location` (
    `id`       INT(16) NOT NULL, 
    `loc_name`   VARCHAR(128), 
    PRIMARY KEY (`id`) 

) 
    ENGINE =INNODB 
    DEFAULT CHARSET =utf8; 

    /*Table structure for table `meeting_location` */ 
DROP TABLE IF EXISTS `meeting_location`; 
CREATE TABLE `meeting_location` (
    `id`       INT(16) NOT NULL AUTO_INCREMENT, 
    `meeting_id`   INT(16) NOT NULL, 
    `main_location_id`  INT(16) NOT NULL, 
    `secondary_location_id`  INT(16) NULL, 
    `name`    VARCHAR(128), 

    PRIMARY KEY (`id`), 
    CONSTRAINT `meeting_location_ibfk_1` FOREIGN KEY (`meeting_id`) REFERENCES `meeting` (`id`) 
ON DELETE CASCADE 
ON UPDATE CASCADE  
    , 
    CONSTRAINT `meeting_location_ibfk_2` FOREIGN KEY (`main_location_id`) REFERENCES `location` (`id`) 
ON DELETE CASCADE 
ON UPDATE CASCADE   
    , 
    CONSTRAINT `meeting_location_ibfk_3` FOREIGN KEY (`secondary_location_id`) REFERENCES `location` (`id`) 
    ON DELETE CASCADE 
ON UPDATE CASCADE 
) 
    ENGINE =INNODB 
    DEFAULT CHARSET =utf8; 

Entities:

@Entity 
@Table(name="location") 
public class Location { 
    @Id 
    @Column(columnDefinition="INT") 
    private int id; 

    @Basic 
    @Column(name="loc_name", length=128) 
    private String locName; 

    public Location() { 
    } 

    public Location(int id) { 
     this.id = id; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getLocName() { 
     return locName; 
    } 

    public void setLocName(String locName) { 
     this.locName = locName; 
    } 
} 


@Entity 
@Table(name="meeting") 
public class Meeting { 
    @Id 
    @Column(columnDefinition="INT") 
    private int id; 

    @OneToMany(targetEntity=MeetingLocation.class, mappedBy="meeting", cascade=CascadeType.ALL) 
    private Set meetingLocations = new HashSet(); 

    @Basic 
    @Column(length=128) 
    private String name; 


    public Meeting() { 
    } 

    public Meeting(int id) { 
     this.id = id; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public Set getMeetingLocations() { 
     return meetingLocations; 
    } 

    public void setMeetingLocations(Set meetingLocations) { 
     this.meetingLocations = meetingLocations; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 


@Entity 
@Table(name="meeting_location") 
public class MeetingLocation { 

    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    @JoinColumn(name="main_location_id", columnDefinition="INT", nullable=false) 
    private Location mainLocation; 

    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    @JoinColumn(name="secondary_location_id", columnDefinition="INT") 
    private Location secondaryLocation; 

    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    @JoinColumn(name="meeting_id", columnDefinition="INT", nullable=false) 
    private Meeting meeting; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(columnDefinition="INT") 
    private int id; 

    @Basic 
    @Column(length=128) 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Location getMainLocation() { 
     return mainLocation; 
    } 

    public void setMainLocation(Location mainLocation) { 
     this.mainLocation = mainLocation; 
    } 

    public Location getSecondaryLocation() { 
     return secondaryLocation; 
    } 

    public void setSecondaryLocation(Location secondaryLocation) { 
     this.secondaryLocation = secondaryLocation; 
    } 

    public MeetingLocation() { 
    } 

    public MeetingLocation(int id) { 
     this.id = id; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 


    public Meeting getMeeting() { 
     return meeting; 
    } 

    public void setMeeting(Meeting meeting) { 
     this.meeting = meeting; 
    } 
} 

Unit Test:

@ManagedBean 
public class SOQuestionTest extends BaseTest { 

    private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, SOQuestionTest.class); 
    public static final int MEETING_ID = 1; 
    public static final String MEETING_1 = "meeting 1"; 

    @Resource 
    protected UserTransaction transaction; 

    @Inject 
    private EndUnitDao<EntityManager> alertDao; 

    @PersistenceContext(name = "euComm-pu") 
    private EntityManager entityManager; 

    @Test 
    public void SOExampleTest() { 

     try { 
      transaction.begin(); 

      Meeting meeting = new Meeting(); 
      meeting.setName(MEETING_1); 
      meeting.setId(MEETING_ID); 

      int mainLocationsSize = 5; 

      List<Location> locations = new ArrayList<Location>(); 
      for (int i = 0; i < (mainLocationsSize * 2); i++) { 
       Location location = new Location(); 
       location.setLocName("location " + i); 
       location.setId(i); 
       locations.add(location); 
       entityManager.persist(location); 
      } 

      for (int i = 0; i < mainLocationsSize; i++) { 
       MeetingLocation meetingLocation = new MeetingLocation(); 
       meetingLocation.setMainLocation(locations.get(i)); 
       meetingLocation.setSecondaryLocation(locations.get(mainLocationsSize + i)); 
       meetingLocation.setMeeting(meeting); 
       meeting.getMeetingLocations().add(meetingLocation); 
      } 
      entityManager.persist(meeting); 

      this.transaction.commit(); 

      Meeting meeting1 = entityManager.find(Meeting.class, MEETING_ID); 
      Assert.assertEquals(MEETING_1, meeting1.getName()); 

      this.transaction.begin(); 
      Meeting meeting2 = entityManager.find(Meeting.class, MEETING_ID); 
      //Here I get the OptimisticLockException: 
      entityManager.remove(meeting2); 
      this.transaction.commit(); 

      Meeting meeting3 = entityManager.find(Meeting.class, MEETING_ID); 
      Assert.assertNull(meeting3); 
     } 
     catch (Exception e) { 
      Assert.fail(e.getMessage()); 
     } 
    } 
} 
  • BaseTest là một lớp tiện ích chúng tôi sử dụng để quản lý các giao dịch, khai thác gỗ và các nhiệm vụ thông thường khác.

Logs:

5057 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1491251091 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 0] 
5057 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5058 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1280539125 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 5] 
5058 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5058 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 323248196 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 1] 
5059 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
5059 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1301992318 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 6] 
5059 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5060 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 2052728503 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 4] 
5060 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5060 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1414992442 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 9] 
5061 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5061 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1812214031 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 2] 
5061 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5062 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 760487425 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 7] 
5062 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5062 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 518757980 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 3] 
5063 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
5063 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 779932859 SELECT t0.loc_name FROM location t0 WHERE t0.id = ? [params=(int) 8] 
5063 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5064 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 604225989 DELETE FROM location WHERE id = ? [params=(int) 0] 
5064 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1653474307 DELETE FROM location WHERE id = ? [params=(int) 5] 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 4677559 DELETE FROM meeting_location WHERE id = ? [params=(int) 3] 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5070 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1283267007 DELETE FROM location WHERE id = ? [params=(int) 1] 
5073 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [3 ms] spent 
5073 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1004931143 DELETE FROM location WHERE id = ? [params=(int) 6] 
5077 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [4 ms] spent 
5078 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1040066455 DELETE FROM meeting_location WHERE id = ? [params=(int) 5] 
5086 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [8 ms] spent 
5086 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 885018785 DELETE FROM location WHERE id = ? [params=(int) 4] 
5087 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
5087 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 851514585 DELETE FROM location WHERE id = ? [params=(int) 9] 
5088 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
5088 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1158016054 DELETE FROM meeting_location WHERE id = ? [params=(int) 1] 
5088 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5088 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 2065936034 DELETE FROM location WHERE id = ? [params=(int) 2] 
5089 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
5090 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1432547991 DELETE FROM location WHERE id = ? [params=(int) 7] 
5092 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [2 ms] spent 
5092 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 49365994 DELETE FROM meeting_location WHERE id = ? [params=(int) 2] 
5094 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [2 ms] spent 
5094 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 429407697 DELETE FROM location WHERE id = ? [params=(int) 3] 
5095 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
5096 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 2020466851 DELETE FROM location WHERE id = ? [params=(int) 8] 
5106 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [10 ms] spent 
5107 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 520296852 DELETE FROM meeting_location WHERE id = ? [params=(int) 4] 
5107 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5107 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 549803608 DELETE FROM meeting WHERE id = ? [params=(int) 1] 
5108 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [1 ms] spent 
Aug 31, 2015 12:45:11 PM org.apache.geronimo.transaction.manager.TransactionImpl beforeCompletion 
WARNING: Unexpected exception from beforeCompletion; transaction will roll back 
<openjpa-2.4.0-nonfinal-1598334-r422266:1599166 nonfatal store error> org.apache.openjpa.persistence.OptimisticLockException: Optimistic locking errors were detected when flushing to the data store. The following objects may have been concurrently modified in another transaction: [com.test.StackOverflowQuestionTest.MeetingLocation-3, com.test.StackOverflowQuestionTest.MeetingLocation-5, com.test.StackOverflowQuestionTest.MeetingLocation-1, com.test.StackOverflowQuestionTest.MeetingLocation-2, com.test.StackOverflowQuestionTest.MeetingLocation-4] 
    at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2359) 
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2207) 
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2105) 
    at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2023) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:527) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:512) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.beforePrepare(TransactionImpl.java:413) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:262) 
    at org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:252) 
    at org.apache.openejb.core.CoreUserTransaction.commit(CoreUserTransaction.java:67) 
    at com.test.shared.commons.BaseTest$Tx.tx(BaseTest.java:121) 
    at com.test.StackOverflowQuestionTest.SOQuestionTest.SOExampleTest(SOQuestionTest.java:106) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80) 
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714) 
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) 
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) 
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127) 
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) 
    at org.testng.TestRunner.privateRun(TestRunner.java:767) 
    at org.testng.TestRunner.run(TestRunner.java:617) 
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) 
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) 
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) 
    at org.testng.SuiteRunner.run(SuiteRunner.java:240) 
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) 
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) 
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198) 
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1123) 
    at org.testng.TestNG.run(TestNG.java:1031) 
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111) 
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204) 
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175) 
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:125) 
Caused by: <openjpa-2.4.0-nonfinal-1598334-r422266:1599166 nonfatal store error> org.apache.openjpa.persistence.OptimisticLockException: An optimistic lock violation was detected when flushing object instance "com.test.StackOverflowQuestionTest.MeetingLocation-3" to the data store. This indicates that the object was concurrently modified in another transaction. 
FailedObject: com.test.StackOverflowQuestionTest.MeetingLocation-3 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:124) 
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:79) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:100) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:88) 
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:550) 
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:120) 
    at org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59) 
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:104) 
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:77) 
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:732) 
    at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131) 
    ... 36 more 
NestedThrowables: 
<openjpa-2.4.0-nonfinal-1598334-r422266:1599166 nonfatal store error> org.apache.openjpa.persistence.OptimisticLockException: An optimistic lock violation was detected when flushing object instance "com.test.StackOverflowQuestionTest.MeetingLocation-5" to the data store. This indicates that the object was concurrently modified in another transaction. 
FailedObject: com.test.StackOverflowQuestionTest.MeetingLocation-5 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:124) 
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:79) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:100) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:88) 
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:550) 
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:120) 
    at org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59) 
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:104) 
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:77) 
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:732) 
    at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131) 
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2207) 
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2105) 
    at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2023) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:527) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.beforeCompletion(TransactionImpl.java:512) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.beforePrepare(TransactionImpl.java:413) 
    at org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:262) 
    at org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:252) 
    at org.apache.openejb.core.CoreUserTransaction.commit(CoreUserTransaction.java:67) 
    at com.test.shared.commons.BaseTest$Tx.tx(BaseTest.java:121) 
    at com.test.StackOverflowQuestionTest.SOQuestionTest.SOExampleTest(SOQuestionTest.java:106) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80) 
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714) 
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) 
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) 
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127) 
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) 
    at org.testng.TestRunner.privateRun(TestRunner.java:767) 
    at org.testng.TestRunner.run(TestRunner.java:617) 
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) 
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) 
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) 
    at org.testng.SuiteRunner.run(SuiteRunner.java:240) 
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) 
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) 
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198) 
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1123) 
    at org.testng.TestNG.run(TestNG.java:1031) 
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111) 
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204) 
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175) 
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:125) 
+1

Giải thích đầu tiên mà tôi có thể thấy là giao dịch đầu tiên của bạn không được cam kết khi bạn cố gắng xóa đối tượng –

+0

Tôi đã thay đổi quản lý giao dịch thành UserTransaction để loại bỏ mối quan ngại này, cùng một lỗi xảy ra. – alex440

Trả lời

1

Từ bạn log:

5064 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 604225989 DELETE FROM location WHERE id = ? [params=(int) 0] 
5064 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 1653474307 DELETE FROM location WHERE id = ? [params=(int) 5] 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> [0 ms] spent 
5065 test-pu TRACE [main] openjpa.jdbc.SQL - <t 1394557075, conn 1722642791> executing prepstmnt 4677559 DELETE FROM meeting_location WHERE id = ? [params=(int) 3] 

Nguyên nhân sâu xa là

cascade=CascadeType.ALL 

Vấn đề là khi bạn chạy

entityManager.remove(meeting2); 

Bạn đang thực sự cố gắng XÓA tất cả các vị trí được hỗ trợ với nó. Vì cuộc họp 2 có hai địa điểm họp nên không thành công (ngay cả khi địa điểm họp thứ hai không bị ràng buộc với một cuộc họp khác!). JPA phát hiện thấy rằng bằng cách nhìn thấy bạn đang cố gắng XÓA một cái gì đó bạn đã không FETCH, đó là lý do tại sao nó ném (có thể sai được xác định) OptimisticLockException.

Một giải pháp có thể là sử dụng một cascadetype khác không sử dụng DELETE.

Nếu bạn không muốn xóa vị trí, hãy sử dụng cascadetype.PERSIST hoặc DETACH.

Các vấn đề liên quan