我在Spring 4中使用Hibernate 4.我创建了自己的会话工厂并使用了Hibernate事务管理器。保存后检索数据时遇到问题。 我使用ProcedureCall保存数据,并在每个方法中打开会话并关闭会话。问题是什么?如果我删除session.close(),那么它工作正常。
public Map<String, Object> savePurchaseOrderInvoiceDetail(String dataString, String order_no,String event, HttpSession hs) throws SQLException, ParseException {
HibernateTransactionManager htmLocal = (HibernateTransactionManager) hs.getAttribute("HibernateTransactionManager");
Session session = htmLocal.getSessionFactory().openSession();
Transaction tx = getTransaction(session);
ProcedureCall qry = session.createStoredProcedureCall("purchase_order_invoice_api");
qry.registerParameter(0, String.class, ParameterMode.IN).bindValue(event);
qry.registerParameter(1, String.class, ParameterMode.IN).bindValue(dataString);
qry.registerParameter(2, String.class, ParameterMode.OUT);
qry.registerParameter(3, String.class, ParameterMode.OUT);
qry.registerParameter(4, Integer.class, ParameterMode.OUT);
qry.registerParameter(5, String.class, ParameterMode.OUT);
ProcedureOutputs output = qry.getOutputs();
String msg = (String) output.getOutputParameterValue(2);
String voucheNo=(String) output.getOutputParameterValue(3);
int invoiceId=(int) output.getOutputParameterValue(4);
String status=(String) output.getOutputParameterValue(5);
Map<String, Object>map=new HashMap<String, Object>();
map.put("msg", msg);
map.put("voucherNo", voucheNo);
map.put("lastInvoiceId", invoiceId);
map.put("status", status);
tx.commit();
session.close();
return map;
}
public Map<String, Object> getInvoiceDetails(String invoicedId,HttpSession hs) throws Exception{
HibernateTransactionManager htmLocal = (HibernateTransactionManager) hs.getAttribute("HibernateTransactionManager");
Session session = htmLocal.getSessionFactory().openSession();
final Map<String, Object>map=new HashMap<String, Object>();
String company=(String) hs.getAttribute("company");
int invoiceIdInt=Integer.valueOf(invoicedId);
String qry = "select inv.*,get_supplier_name(inv.Company,inv.Identity) AS CUSTOMER_NAME from invoice_tab inv";
Query query = session.createSQLQuery(qry).addEntity(Invoice.class);
query.setCacheable(false);
List<Invoice> invoiceList = query.list();
for (int i = 0; i < invoiceList.size(); i++) {
Invoice invoiceObj=invoiceList.get(i);
//Business logic
}
session.close();
return map;
}
答案 0 :(得分:0)
您正在努力使用Spring,更不用说您拥有一个服务(或者可能是存储库)这一事实,这取决于它是一个Web应用程序。两件事都很糟糕。
将@Transactional
注释添加到包含这些方法的类中,并启用注释驱动的事务管理。而不是绕过HttpSession
只是注入您的依赖项,在这种情况下是SessionFactory
。
不要自己创建会话使用当前会话,即sessionFactory.getCurrentSession()
来获取事务会话。
@Service
@Transactional
public class YourService {
private final SessionFactory sessionFactory;
public YourService(SessionFactory sf) {
this.sessionFactory=sf;
}
public Map<String, Object> savePurchaseOrderInvoiceDetail(String dataString, String order_no,String event) throws SQLException, ParseException {
Session session = sessionFactory.getCurrentSession();
ProcedureCall qry = session.createStoredProcedureCall("purchase_order_invoice_api");
qry.registerParameter(0, String.class, ParameterMode.IN).bindValue(event);
qry.registerParameter(1, String.class, ParameterMode.IN).bindValue(dataString);
qry.registerParameter(2, String.class, ParameterMode.OUT);
qry.registerParameter(3, String.class, ParameterMode.OUT);
qry.registerParameter(4, Integer.class, ParameterMode.OUT);
qry.registerParameter(5, String.class, ParameterMode.OUT);
ProcedureOutputs output = qry.getOutputs();
String msg = (String) output.getOutputParameterValue(2);
String voucheNo=(String) output.getOutputParameterValue(3);
int invoiceId=(int) output.getOutputParameterValue(4);
String status=(String) output.getOutputParameterValue(5);
Map<String, Object>map=new HashMap<String, Object>();
map.put("msg", msg);
map.put("voucherNo", voucheNo);
map.put("lastInvoiceId", invoiceId);
map.put("status", status);
return map;
}
public Map<String, Object> getInvoiceDetails(int invoicedId, String company) throws Exception{
Session session = sessionFactory.getCurrentSession();
final Map<String, Object>map=new HashMap<String, Object>();
String qry = "select inv.*,get_supplier_name(inv.Company,inv.Identity) AS CUSTOMER_NAME from invoice_tab inv";
Query query = session.createSQLQuery(qry).addEntity(Invoice.class);
query.setCacheable(false);
List<Invoice> invoiceList = query.list();
for (int i = 0; i < invoiceList.size(); i++) {
Invoice invoiceObj=invoiceList.get(i);
//Business logic
}
return map;
}
}
如上所述。
我真正得到的是为什么你甚至使用hibernate,因为你正在创建自己的查询而不使用HQL或任何东西来获取实体。你唯一使用hibernate的是映射,也可以用普通的SQL来完成,为你的sql结果映射添加hibernate只是为了在我的书中有点矫枉过正。