通过hibernate调用的存储过程不会提交数据库中的更改

时间:2017-04-03 09:58:15

标签: spring hibernate session

我们正在使用Spring和hibernate开发一个应用程序。 dao图层类如下:

@Autowired
private StoredDao storedDao;

@PersistenceUnit
private EntityManagerFactory emf;

public boolean method() throws Exception {

EntityManager em;
Session session;
Transaction tx;

try{

em = emf.createEntityManager();
session = em.unwrap(Session.class);
tx = session.beginTransaction();
...
...
...
storedDao.processBills(billId, billStatus, billApprover);
...
...
tx.commit();
} catch(Exception e){
  tx.rollback();
}

}

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
@Override
    public void processBills(int billId, int billStatus, String billApprover, Session session){

try{

   final Work processBillCaller = buildStoredProcCaller(billId, billStatus, billApprover);

session.doWork(processBillCaller);
} catch (Exception e){

throw new Exception("message");

}

}

private Work buildStoredProcCaller(int billId, int billStatus, String billApprover) {



        return new Work() {
            @Override
            public void execute(Connection con) throws SQLException {


                    try (CallableStatement callableStmt = con.prepareCall(<procName>);) {

                        callableStmt.setInt(1, billId);
                        callableStmt.setString(2, billStatus);
                        callableStmt.setInt(3, billApprover);


                        callableStmt.executeUpdate();
                    } catch (Exception e) {

                        throw new SQLException("message");
                    }               

            }
        };

    }

执行方法()中的所有查询。此外,存储过程在方法processBills中执行。在日志中,消息如下:

[ABC1] [DEBUG] [org.hibernate.SQL] {call procName?,?,? }

但是未提交存储过程的结果。

在存储过程调用之前和之后调用了很多session.save()和session.merge()。执行tx.commit()时,除了存储过程结果外,所有内容都会被提交。没有错误。

我还尝试评论@Transactional,然后运行上面的代码流程。但是,存储过程代码仍然没有被提交。

请让我知道我做错了什么。

1 个答案:

答案 0 :(得分:0)

您好我找到了答案。在调用存储过程之前,新帐单尚未保留在数据库中。它只在调用transaction.commit()时才会持久化。因此,当存储过程正在运行时,要处理的帐单不在数据库中。

所以现在在存储过程调用之前,现在我调用session.flush()然后执行存储过程。它有效。