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

Java 使用session.save保存对象时,Hibernate不刷新会话?,java,spring,hibernate,spring-mvc,hibernate-session,Java,Spring,Hibernate,Spring Mvc,Hibernate Session,首先看一下下面的代码,我有三个主要模型来管理仓库和仓库库存,还有另一个名为仓库库存锁的模型,当其他进程想要使用这些模型时,可以临时锁定/解锁一些仓库库存: public class StoreHouse { private String name; private Double currentAmount; } public class StoreHouseInventory { private StoreHouse storeHouse; private

首先看一下下面的代码,我有三个主要模型来管理
仓库
仓库库存
,还有另一个名为
仓库库存锁
的模型,当其他进程想要使用这些模型时,可以临时锁定/解锁一些
仓库库存

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);
    }
}
问题是,当在
仓库服务.syncCurrentInventory
中调用
仓库库存服务.sumOfLock
时,它不知道
仓库库存锁服务.add
方法中的
方法。addDetailtoPermitFromStoreInventory
方法的更改,并错误地计算锁的总数


我想这是因为我调用
InventoryLockService.add
时未刷新会话。如果这是真的,为什么hibernate在此更改期间不flsuh会话?如果没有,我该怎么办

作为
istorehouse inventory lockservice.add
从已附加事务的方法中调用,然后将同一事务传播到
add
方法,因此直到外部
adddetailtopermitfromstorehouse inventory
完成,才会进行刷新

您的一个快速解决方案是使用REQUIRES\u新事务传播类型标记
add
方法:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void add(..){..}

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

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

在同一事务中,数据已经可见,你不需要新的交易。如果数据不可见,则会发生其他情况。@M.Deinum,您的意思是没有nedd可以使用
@Transactional(propagation=propagation.REQUIRES_NEW)
?如何解决这个问题?在sumOfLock方法的查询过程中。。可能在调用之前没有将更改刷新到数据库。理论上是的,如果查询使用在当前事务中受影响的实体,则应该是这样。首先,您的代码有缺陷,您永远不应该捕获异常并吞咽,您的代码破坏了正确的tx管理。数据在同一事务中可见,hibernate在查询数据库时会自动刷新挂起的更改。如果没有发生这种情况,你很可能在冬眠后做一些事情。为同步方法(和相关对象)添加代码。很抱歉,这是我的错,我删除了
try,catch