title: EJB Singleton and JPA optimistic locking throws OptimisticLockException
body: <p>I have a problem that relates to an EJB singleton and database locking.</p>
  
  <p>The following class represents an entity for consignment numbers.
  It is mandatory that each consignment number is unique. Please note, that this
  class has been prepared for optimistic locking by defining the version property.</p>
  
  <pre><code>@Entity
  @NamedQuery(name = Connote.FIND_NEXT, query = "SELECT c from Connote c WHERE c.consumed = false")
  public class Connote implements Serializable {
  
      /**
      * 
      */
      private static final long serialVersionUID = 1L;
      public static final String FIND_NEXT = "Connotes.FindNext";
  
      @Id
      @Size(max = 15)
      private String connote;
  
      @Version
      private Long version;
  
      private Date insertedDate;
      private boolean consumed;
      private Date consumedDate;
  
      public Connote() {
          super();
      }
  
      public String getConnote() {
          return connote;
      }
  
      public void setConnote(String connote) {
          this.connote = connote;
      }
  
      public Date getInsertedDate() {
          return insertedDate;
      }
  
      public void setInsertedDate(Date insertedDate) {
          this.insertedDate = insertedDate;
      }
  
      public boolean isConsumed() {
          return consumed;
      }
  
      public void setConsumed(boolean consumed) {
          this.consumed = consumed;
      }
  
      public Date getConsumedDate() {
          return consumedDate;
      }
  
      public void setConsumedDate(Date consumedDate) {
          this.consumedDate = consumedDate;
      }
  
      public Long getVersion() {
          return version;
      }
  
      public void setVersion(Long version) {
          this.version = version;
      }    
  }
  </code></pre>
  
  <p>A delivery company provides a set of many thousand consignment numbers, which
  will be persisted to the database.</p>
  
  <p>When creating a new freight order, the next "unconsumed" consignment number from this set
  should be retrieved and delivered to the requesting service.</p>
  
  <p>The service in this case is an EJB singleton, which provides the service method
  "calculateConnoteNumber()". As the ejb class is annotated with "@Lock(LockType.WRITE)"
  concurrent access to this method should be prevented. Upon retrieval of the next unconsumed
  entity, the flag "consumed" will be flagged to true and the date of consumption will be set.
  Finally the updated entity will be merged and the value of connote is being returned.</p>
  
  <p>However, during load testing we experienced  "OptimisticLockExceptions" (avg. 5 from 1000)
  when creating new orders.</p>
  
  <p>What I do not understand is, how this is possible as the access to the business method and 
  thereby to the transaction should be sequential.</p>
  
  <p>Changing the locking type on persistence layer by setting</p>
  
  <pre><code>query.setLockMode(LockModeType.PESSIMISTIC_WRITE); 
  </code></pre>
  
  <p>works.</p>
  
  <p>To my mind this should not be necessary and optimistic locking should be enough as long as
  concurrent access to the business method is prevented.
  Did I miss something here?</p>
  
  <p>Environment used: WildFly 8.2.0, MySql 5.7, xa-datasource</p>
  
  <pre><code>/**
   * Session Bean implementation class ConnoteCalculatorFacade
   */
  @Singleton
  @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
  @TransactionManagement(TransactionManagementType.CONTAINER)
  @Lock(LockType.WRITE)
  public class ConnoteCalculatorFacade {
  
      private final Logger logger = LoggerFactory.getLogger(this.getClass());
  
      @PersistenceContext(unitName = "some_unit_name")
      private EntityManager entityManager;
  
      /**
       * Default constructor.
       */
      public ConnoteCalculatorFacade() {
          if (logger.isDebugEnabled()) {
              logger.debug("ConnoteCalculatorFacade instantiated!");
          }
      }
  
      @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
      public String calculateConnoteNumber() throws OrderManagementException {
          if (logger.isInfoEnabled()) {
              logger.info("Retrieving new RS connote!");
          }
  
          try {
              Query query = this.entityManager.createNamedQuery(Connote.FIND_NEXT);
              query.setMaxResults(1);
              //query.setLockMode(LockModeType.PESSIMISTIC_WRITE); &lt;-- works when using pessimistic_write
  
              List&lt;Connote&gt; validConnoteList = query.getResultList();
  
              if (validConnoteList.size() == 1) {
  
                  Connote connote = validConnoteList.get(0);
                  connote.setConsumed(true);
                  connote.setConsumedDate(new Date());
  
                  this.entityManager.merge(connote);
                  this.entityManager.flush();
  
                  return connote.getConnote();
              } else {
                  throw new OrderManagementException(AddressLabelExceptionReason.NO_CONNOTES_AVAILABLE);
              }
  
          } catch (Exception e) {
              logger.error("Error calculating connote number! ",e);
              throw new OrderManagementException(AddressLabelExceptionReason.ERROR_ASSIGNING_CONNOTE);
          }
  
      }
  }
  </code></pre>
  
  <p><strong>Update</strong>
  The service is being consumed by another stateless, local EJB "PDFCreatorFacade", that injects the singleton</p>
  
  <pre><code>@EJB
  private ConnoteCalculatorFacade connoteCalculator;
  ...
  </code></pre>
  
  <p>and then calls the method on the singleton in it's (non annotated) business method.</p>
  
  <pre><code>public Label createPdfDocument(Label label) throws  OrderManagementException {
      ....
      String connoteNumber = connoteCalculator.calculateConnoteNumber();
      ....
  }
  </code></pre>