title: Java JPA PessimisticLockingFailureException could not execute statement
body: <p>I got a Java JPA application where I have a Websocket controller to handle my websocket requests. Updating an entity was working just fine in other functions but when I try to update a <code>BordRowItem</code> entity it does work when I'm setting a boolean in the <code>BordRowItemTask</code> on true/false but not when I try to update the <code>description</code> of the <code>BordRowItem</code>. Both updating the <code>BordRowItemTask</code> and the <code>description</code> are in the same method. The method is called with a single purpose: not both <code>BordRowItemTask</code> and the <code>description</code> will be updated at the same time. However, I'm getting a <code>PessimisticLockingFailureException</code></p>
  
  <p>Code where I update the task entity:</p>
  
  <pre><code>Optional&lt;BordRowItem&gt; optionalBordRowItem = bordRowItemRepository.findById(object.getInt("id"));
  BordRowItem item = optionalBordRowItem.get();
  JSONObject task = object.getJSONObject("task");
  List&lt;BordRowItemTask&gt; tasks = item.getTasks();
  
  Hibernate.initialize(tasks);
  
  if(task.has("id")) {
      Optional&lt;BordRowItemTask&gt; optionalBordRowItemTask = bordRowItemTaskRepository.findById(task.getInt("id"));
  
      if(optionalBordRowItemTask.isPresent()) {
          for(BordRowItemTask bordRowItemTask : tasks) {
              if(bordRowItemTask.getId() == optionalBordRowItemTask.get().getId()) {
                  bordRowItemTask.setDescription(task.getString("description"));
                  bordRowItemTask.setChecked(task.getBoolean("checked"));
  
                  BordRowItemEvent event = new BordRowItemEvent("i have '" + bordRowItemTask.getDescription() + (bordRowItemTask.isChecked() ? "' changed" :  "' not"));
                  event.setBordRowItem(item);
                  events.add(event);
  
                  bordRowItemTaskRepository.save(bordRowItemTask);
                  entityManager.flush();
                  break;
              }
          }
      }
  }
  </code></pre>
  
  <p>Code where I update the description:</p>
  
  <pre><code>String msg = (item.getDescription() != null &amp;&amp; !item.getDescription().isEmpty()) ? " van '" + item.getDescription() + "'" : "";
  
  BordRowItemEvent event = new BordRowItemEvent("i changed a thing" + msg + " to '" + object.getString("description") + "'");
  event.setBordRowItem(item);
  events.add(event);
  
  item.setDescription(object.getString("description"));
  </code></pre>
  
  <p>End of the websocket method to save the item:</p>
  
  <pre><code>bordRowItemRepository.save(item);
  entityManager.flush();
  entityManager.getTransaction().commit();
  
  entityManager.close();
  </code></pre>
  
  <p>BordRowItem:</p>
  
  <pre><code>import com.fasterxml.jackson.annotation.JsonIgnore;
  import org.hibernate.annotations.CreationTimestamp;
  import org.hibernate.annotations.UpdateTimestamp;
  import org.springframework.lang.Nullable;
  
  import javax.persistence.*;
  import javax.validation.constraints.NotNull;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  
  @Entity
  @Table(name = "bord_row_items")
  public class BordRowItem
  {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private int id;
  
      @CreationTimestamp
      @JsonIgnore
      private Date created_at;
  
      @UpdateTimestamp
      @JsonIgnore
      private Date updated_at;
  
      @JsonIgnore
      private Date deleted_at;
  
      @NotNull
      private Integer created_by;
  
      @NotNull
      private String title;
  
      @Column(name = "story_points")
      private Integer storyPoints;
  
      private Date expiry_date;
  
      private String description;
  
      @OneToMany(mappedBy = "bordRowItem")
      private List&lt;BordRowItemTask&gt; tasks;
  
      @OneToMany(mappedBy = "bordRowItem")
      private List&lt;BordRowItemEvent&gt; events;
  
      @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
      @JoinTable(
              name = "bord_row_item_labels",
              joinColumns = @JoinColumn(name = "bord_row_item_id"),
              inverseJoinColumns = @JoinColumn(name = "bord_row_label_id"))
      private List&lt;BordRowLabel&gt; labels;
  
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "bord_row_id")
      @JsonIgnore
      private BordRow bordRow;
  
      public BordRowItem() {
          this.tasks = new ArrayList&lt;&gt;();
          this.labels = new ArrayList&lt;&gt;();
          this.events = new ArrayList&lt;&gt;();
      }
  
      public BordRowItem(String title) {
          this.title = title;
          this.tasks = new ArrayList&lt;&gt;();
          this.labels = new ArrayList&lt;&gt;();
          this.events = new ArrayList&lt;&gt;();
      }
  
      //getters and setters
  }
  </code></pre>
  
  <p>Error: </p>
  
  <pre><code>org.springframework.dao.PessimisticLockingFailureException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.PessimisticLockException: could not execute statement
      at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:292) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:254) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:537) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744) ~[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:712) ~[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:619) ~[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:372) ~[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) ~[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178) ~[spring-data-jpa-2.2.0.RELEASE.jar:2.2.0.RELEASE]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at com.sun.proxy.$Proxy130.save(Unknown Source) ~[na:na]
      at com.myproject.project.project.controller.WebSocketController.updateBordRowItem(WebSocketController.java:323) ~[main/:na]
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_221]
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_221]
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_221]
      at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_221]
      at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) ~[spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) ~[spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:565) [spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:511) [spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:94) [spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:520) [spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:454) [spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:144) [spring-messaging-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_221]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_221]
      at java.lang.Thread.run(Thread.java:748) [na:1.8.0_221]
  Caused by: org.hibernate.PessimisticLockException: could not execute statement
      at org.hibernate.dialect.MySQLDialect$3.convert(MySQLDialect.java:536) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3392) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3265) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3666) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:149) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_221]
      at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:349) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:108) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1358) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:436) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3235) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2403) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:533) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
      ... 30 common frames omitted
  Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
      at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025) ~[mysql-connector-java-8.0.18.jar:8.0.18]
      at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-3.4.1.jar:na]
      at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.1.jar:na]
      at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
      ... 51 common frames omitted
  
  </code></pre>