Search code examples
javaspringhibernatespring-transactions

Changes made in a @Transactional method are not reflected to the Entity


I have the following method in my Service Layer, which

  1. Retrieves an entity by ID
  2. Executes an update to the entity
  3. Retrieves and returns the same entity

    @Transactional
    @Override
    public Order acceptOrder(long orderId){
        Order Order = getOrderById(orderId);                                  // 1
        orderDao.updateOrderStatus(OrderStatus.PENDING_COMPLETION, orderId);  // 2
        return getOrderById(orderId);                                         // 3
    }   
    

    The service's method getOrderById

    @Override
    public Order getOrderById(long id) {
        return orderDao.get(Order.class, id);
    }
    

And the DAO's method updateOrderStatus

    @Override
    public int updateOrderStatus(AppEnums.OrderStatus status, long orderId) {
        String query = "update Order set orderStatus=:status where id=:orderId";
        Query q = getHibernateSession().createQuery(query);
        q.setParameter("status", status);
        q.setParameter("orderId", orderId);
        return q.executeUpdate();
    }

When the method executes the DB is updated successfully but the returned entity's status does not reflect the updated status value. Shouldn't changes made in the same transaction be visible by default?


Solution

  • You may,

    Update your entity and save it

    (As M.Deinum suggested in the comments)

    order.setOrderStatus(OrderStatus.PENDING_COMPLETION);  //2
    return salesOrderDao.saveOrUpdate(order);              //3
    

    Commit your transaction once it's updated

    @Transactional
    @Override
    public Order acceptOrder(long orderId){
        Order order = getOrderById(orderId);                                  // 1
        orderDao.updateOrderStatus(OrderStatus.PENDING_COMPLETION, orderId);  // 2
        //commit the transaction                                              // 3
        return getOrderById(orderId);                                         // 4
    }  
    

    Note: You will need to access the transaction someway.

    Remove the instance from the session cache

    You can do this using Session.evict

    orderDao.updateOrderStatus(OrderStatus.PENDING_COMPLETION, orderId);  //2
    hibernateSession.evict(order);                                        //3
    return getOrderById(orderId);                                         //4
    

    Note: You will need to access the HibernateSession

    But you can do something like this mentioned in this answer,

    @Transactional
    public void method1(){
        this.updateM1Service();
        this.getDataService();
    }
    
    @Transactional (propagation = Propagation.REQUIRES_NEW)
    public void updateM1Service(){
        dao.updateM1();
    }
    
    @Transactional
    public void getDataService(){
        dao.getData();
    }