0 Replies Latest reply on Nov 2, 2012 2:08 PM by lafr

    No pessimistic locking of Entity

    lafr

      Using JBoss AS7 7.2.0.Alpha1-SNAPSHOT, build from the current sources at github including Hibernate 4.1.6. Entity Beans are EJB 3.1 / JPA 2.0.

       

      I want to have a pessimistic locking of an entity bean to get a serialization of of the modification from different threads.

      Parent table is mbi_msghd, unique msghd_serial, Entity Bean named MbiMsghd.

      Child table is mbi_msgpa, unique msghd_serial + part_no, Entity Bean named MbiMsgpa.

      mbi_msgpa.msghd_serial is FK to mbi_msghd.msghd_serial.

       

      From MbiMsghd.java:


      /** Relation with MbiMsgpa. */

      @OneToMany( cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true )

      @OrderBy( "msghdSerial ASC, partNo ASC" )

      @JoinColumn( name = "msghd_serial", referencedColumnName = "msghd_serial", insertable = false, updatable = false )

      private Collection<MbiMsgpa> mbiMsgpa;

       

      Business logic is implemented in a stateless session bean. Method is marked with

      @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

       

      Within the method I do first

      MbiMsghd mbiMsghd = this.entityManager.find( MbiMsghd.class, msghdSerial, LockModeType.PESSIMISTIC_READ );

       

      and then

              MbiMsgpa mbiMsgpa = new MbiMsgpa();
              mbiMsgpa.setMsghdSerial( mbiMsghd.getMsghdSerial() );
              Collection<MbiMsgpa> mbiMsgpas = mbiMsghd.getMbiMsgpa();
              if ( mbiMsgpas == null ) {
                  mbiMsgpa.setPartNo( Integer.valueOf( 1 ) );
              } else {
                  mbiMsgpa.setPartNo( Integer.valueOf( mbiMsgpas.size() + 1 ) );
              }

       

      But if this method is callled in parallel from different callers it happens, that I get an exception saying

      Caused by: java.sql.SQLException: Could not insert new row - duplicate value in a UNIQUE INDEX column (Unique Index:mbi_msgpa1).

      meaning that the same partNo was given to a new MbiMsgpa entity.

       

      From what I read I understood, that reading the MbiMsghd entity with LockModeType PESSIMISTIC_READ should prevent other threads from doing the same until the first one, holding the lock, finishes its transaction.

      So the scond one should see also  all the inserted childs and give the next one the correct value for partNo.