Разработваме приложение с пролет и хибернация. Класът на слоя 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 () и сесия.merge (), извикани преди и след обаждането на запомнената процедура. Когато се изпълнява tx.commit (), всичко се изпълнява, с изключение на резултатите от съхранената процедура. Няма грешка.
Също така се опитах да коментирам @Transactional и след това изпълнявайки горния кодов поток. Но все пак, кода на запомнената процедура не се ангажира.
Моля, уведомете ме какво правя грешно.
Отговори:
0 за отговор № 1Здравейте намерих отговора на това. Преди да се обади на съхранената процедура, новата сметка все още не е запазена в базата данни. Той се запазва само когато се обажда transaction.commit (). Следователно, когато запомнената процедура е изпълнена, сметката, която трябва да бъде обработена, не е в базата данни.
Така че сега преди запомнянето на запомнената процедура, сега се обаждам на session.flush () и след това се изпълнява запаметената процедура. Работи.