0

Spring 4 で Hibernate 4 を使用しています。独自のセッション ファクトリを作成し、Hibernate Transaction Manager を使用しました。保存後にデータを取得する際に問題が発生しました。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;
}
4

1 に答える 1

0

Web アプリケーションであるという事実に依存するサービス (ま​​たはおそらくリポジトリ) を持っているという事実は言うまでもなく、Spring を使用しようと懸命に努力しています。どちらも悪いことです。

これらのメソッドを含むクラスにアノテーションを追加し、@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;
    }
}   

上記のようなもの。

私が実際に得ていないのは、独自のクエリを作成していて、エンティティを取得するために HQL などを使用していないため、休止状態を使用している理由です。休止状態を使用する唯一のことはマッピングであり、それはプレーンSQLでも実行できます。SQL結果のマッピングのためだけに休止状態をプロジェクトに追加することは、私の本では少しやり過ぎです。

于 2014-12-13T16:08:30.067 に答える