使用session.save保存对象时,Hibernate不刷新会话?

时间:2017-02-21 10:58:53

标签: java spring hibernate spring-mvc hibernate-session

首先看看下面的代码,我有三个主要模型来管理StoreHouseStoreHouseInvetory,并有其他模型名为StoreHouseInventoryLock来临时锁定/解锁一些金额当其他进程想要使用这些模型时,StoreHouseInvetory得到:

public class StoreHouse {
    private String  name;
    private Double  currentAmount;
}

public class StoreHouseInventory {
    private StoreHouse  storeHouse;
    private Good        good;
    private Double      amount;
}

public class StoreHouseInventoryLock {
    private StoreHouseInventory     inventory;
    private Double                  amount;
}

@Service
public class PermitService implements IPermitService {

    @Autowired
    private IStoreHouseInventoryLockService storeHouseInventoryLockService;

    @Autowired
    private IStoreHouseService storeHouseService;

    @Override
    @Transactional
    public void addDetailToPermitFromStoreHouseInventory(long permitId, long storeHouseId, long inventoryId, double amount) {

        // do some business logic here

        /* save is simple method
         * and uses Session.save(object)
        */
        storeHouseInventoryLockService.add(inventoryId, +amount);

        // do some business logic here
        storeHouseService.syncCurrentInventory(storeHouseId);   
    }
}

@Service
public class StoreHouseService implements IStoreHouseService {

    @Autowired
    private IStoreHouseInventoryService storeHouseInventoryService;

    @Autowired
    private IStoreHouseInventoryLockService storeHouseInventoryLockService;

    @Transactional
    public void syncCurrentInventory(storeHouseId) {
        /* is a simeple method that use query like below
         * select sum(e.amount)
         *   from StoreHouseInventory
         *  where e.storeHouse.id = :storeHouseId
         */
        Double sumOfInventory = storeHouseInventoryService.sumOfInventory(storeHouseId);
        /* is a simeple method that use query like below
         * select sum(e.amount)
         *   from StoreHouseInventoryLock
         *  where e.storeHouseInventory.storeHouse.id = :storeHouseId
         */
        Double sumOfLock = storeHouseInventoryService.sumOfLock(storeHouseId);

        // load method is a simple method to load object by it's id
        // and used from Session.get(String entityName, Serializable id)
        StoreHouse storeHouse = this.load(storeHouseId);
        storeHouse.setCurrentAmount(sumOfInventory - sumOfLock);

        this.save(storeHouse);
    }
}

问题是,在storeHouseInventoryService.sumOfLock中调用StoreHouseService.syncCurrentInventory时,它不会意识到storeHouseInventoryLockService.add方法中PermitService.addDetailToPermitFromStoreHouseInventory方法的更改,并且错误地计算了锁的总和。

我认为这是因为当我呼叫storeHouseInventoryLockService.add时会话没有被刷新。如果这是真的,为什么hibernate在这个变化期间没有flsuh会话?如果没有,我该怎么办?

2 个答案:

答案 0 :(得分:0)

从已经附加了事务的方法中调用IStoreHouseInventoryLockService.add,然后将相同的事务传播到add方法,因此直到外部{{ 1}}完成。

快速解决方案是使用REQUIRES_NEW事务传播类型标记addDetailToPermitFromStoreHouseInventory方法:

add

现在该方法完成后,即使存在外部事务,所有持久性更改也将在退出时刷新到数据库。

答案 1 :(得分:0)

如果当前正在执行的查询与未刷新的表语句不重叠,则可以安全地忽略刷新。