2

ずっと前に、次のように、DetachedCriteria を使用して非常に小さなアプリケーションでの生活を楽にする one-class-hibernate-util を作成しました。

import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.DetachedCriteria;

/* WARNING: This utility was projected only for applications of one operation per use per mapping!
Using it for multiple operations characterizes the anti-pattern "session-per-operation". */
public class HibernateUtil {
    private static final int SEARCH = 0;
    private static final int LIST = 1;
    private static final int SAVE = 2;
    private static final int UPDATE = 3;
    private static final int SAVE_OR_UPDATE = 4;
    private static final int DELETE = 5;
    private static final int MERGE = 6;
    private static SessionFactory SESSION_FACTORY;

    // Single session factory instantiation
    static {SESSION_FACTORY = new Configuration().configure().buildSessionFactory();}

    // Opens the session and executes only one operation on the transaction
    private static Object executeTransaction(Object object, int operation) {
        Object output = null;
        Session session = SESSION_FACTORY.openSession();
        Transaction transaction = null;
        try {
            transaction = session.beginTransaction();
            switch (operation) {
                case SEARCH: output = ((DetachedCriteria) object).getExecutableCriteria(session).uniqueResult(); break;
                case LIST: output = ((DetachedCriteria) object).getExecutableCriteria(session).list(); break;
                case SAVE: session.save(object); break;
                case UPDATE: session.update(object); break;
                case SAVE_OR_UPDATE: session.saveOrUpdate(object); break;
                case DELETE: session.delete(object); break;
                case MERGE: session.merge(object); break;
                default: throw new HibernateException("No operation was executed on the database.");
            }
            transaction.commit();
        } finally {
            session.close();
        }
        return output;
    }

    // Usable methods, named accordingly to the operation:
    public static Object searchCriteria(DetachedCriteria criteria) {return executeTransaction(criteria, SEARCH);}
    public static List<?> listCriteria(DetachedCriteria criteria) {return (List<?>) executeTransaction(criteria, LIST);}
    public static void save(Object object) {executeTransaction(object, SAVE);}
    public static void update(Object object) {executeTransaction(object, UPDATE);}
    public static void saveOrUpdate(Object object) {executeTransaction(object, SAVE_OR_UPDATE);}
    public static void delete(Object object) {executeTransaction(object, DELETE);}
    public static void merge(Object object) {executeTransaction(object, MERGE);}
}

これにより、 を呼び出してデータベースと対話できますがHibernateUtil.searchCriteria()/listCriteria()/save()/update()/saveOrUpdate()/delete()/merge()、実際には操作ごとのセッションの性質により、非常にまれな状況 (小さなアプリケーション) で使用します。

問題は、仲間の同僚がより大きなアプリケーションで DAO を使用していて、適切な DAO パターンを使いすぎていることを発見したところです。私のせいです。オーバーヘッドや過負荷などの副作用の可能性が心配ですが、どのような問題を心配する必要があるのか​​正確にはわかりません。これは、彼らのアプリケーションで DAO の再作成を開始するのに十分危険ですか?

より経験豊富なプログラマーまたは DBA の担当者の何人かが、ここで私にいくつかの光を共有できますか? よろしくお願いします。

編集

セッションを閉じるように変更しました。遅延初期化エラーを回避するために私が今やっていることはlazy="false"、hbm.xml のすべての多対 1 マッピングで設定することです。

4

1 に答える 1

1

あなたが心配すべき主な問題は、トランザクションの完全性だと思います。いくつかのセーフ/更新/保存または更新/削除操作を 1 つのトランザクションで実行する必要があるが、このヘルパー クラスの「おかげで」それぞれ独自のトランザクションで実行される多くのユース ケースが見つかると思います。

もう 1 つの問題は、このヘルパー クラスを使用すると、1 つではなく 2 つのセッション ファクトリが強制的に使用されることです。これは、このヘルパー クラスが独自のプライベート セッション ファクトリを使用するためです。

このクラスを削除し、Spring または EJB を使用して宣言型のトランザクション管理を行い、トランザクションごとのセッション パターンまたはビューでセッションを開くパターンを使用します。どちらも、セッションがある時点で確実に閉じられるようにします。

于 2012-07-01T07:38:57.803 に答える