2
votes

I've faced with the following problem. Error "Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1;" is appearing while deleting object with @Scheduled method invocation. Error appears only while @Scheduled invocation, I have got an error with the first call of deleteInactiveOrders(). If scheduled method invoked manually from the controller - everything is ok, error isn't appeared. I assume that error relates to multithreading issue, but i can't figure out how to fix it.

Service method:

@Transactional
@Scheduled(cron = "*/30 * * * * *")
public void deleteInactiveOrders() {
   orderDAO.deleteInactiveOrders();
}

orderDAO.deleteInactiveOrders():

public void deleteInactiveOrders() {
List<Order> allInactiveOrdersList = sessionFactory.getCurrentSession().createQuery("from Order where orderDate <= sysdate-1").list();
     if (allInactiveOrdersList.size() >=1 ){

      for (Order order: allInactiveOrdersList){
          User user = order.getUser();
          user.removeOrder(order);
        }
      }
    }

Error:

DEBUG [org.hibernate.SQL] [] pool-2-thread-1 delete from orders where orderId=? DEBUG [org.hibernate.SQL] [] pool-3-thread-1 delete from orders where orderId=? DEBUG [org.hibernate.SQL] [] pool-3-thread-1 delete from orders where orderId=? INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] [] pool-2-thread-1 HHH000010: On release of batch it still contained JDBC statements ERROR [org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler] [] pool-2-thread-1 Unexpected error occurred in scheduled task. org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

Entity:

@Entity
@Table(name = "orders")
public class Order implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int orderId;
    .....

    @ManyToOne
    @JoinColumn(name = "userId", insertable = true, updatable = false)
    private User user;

    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(mappedBy = "order", orphanRemoval=true)
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    private List<ExchangeTransaction> exchangeTransactions = new ArrayList<ExchangeTransaction>();

    public int getId() {
        return orderId;
    }

UPDATE: i've found solution for this issue. The problem was with the two contexts and the dependencies between them, i mean ContextLoaderListener and DispatcherServlet. Now I work only with one context and this problem has gone.

1
Afaik, you are accessing order in your list, so, you cannot delete it at same time.We are Borg
But when deleteInactiveOrders() is invoked manually from the controller everything is ok. This error happens only with scheduling invocation.ivan_ochc
user.removeOrder(order); in here you simply remove the entity from the list? or you perform a call to DB?AntJavaDev
Here is the code: orders.remove(order); - remove order from the list order.setUser(null); - set null to the User entity variableivan_ochc

1 Answers

0
votes

You dont need the following statement in your code sessionFactory.getCurrentSession().delete(order);, you are performing a user.removeOrder(order); on an entity thats already attached to session so it will take care of deletion of order.