0

私の質問は非常に奇妙で理解しにくいことを知っています

プロジェクトの構造を作成します。しかし、私はさまざまな問題に直面するたびに、could not initialize proxy - No session againまたはNot serializable exception

アドバイスや助けが欲しいです。アノテーションを使用しようとしtransactionalていますが、どの場合に を使用すればよいかわかりませんimplements Serializable。もちろん、ビュー スコープで Bean を使用する場合は、クライアントの保存方法を使用する必要があり、Bean は implenebts seriailzable である必要があることはわかっています。他の非プリミティブ フィールドを使用する場合、そのフィールドもシリアライズ可能である必要があります。これは、インターフェイス IDao と ITestSystemService の両方で inmplenet Serializable を使用しても問題がないことを意味します。

私の汎用 DAO

public interface IDao<T> extends Serializable{
    List<T> getAll() throws DAOException;
    T get(Long id) throws DAOException;
}

DAO の実装

@Repository("subjectDAO")
@Scope("prototype")
public class SubjectHibernateDAO implements ISubjectDAO{

    private static final long serialVersionUID = 1L;

    private static final Logger logger = Logger.getLogger(SubjectHibernateDAO.class);

    @Autowired
    private SessionFactory hibernateSessionFactory;
    //getter and setter

    @SuppressWarnings("unchecked")
    @Override
    public List<Subject> getAll() throws DAOException {
        Session session = hibernateSessionFactory.getCurrentSession();

        Transaction transaction = null;
        List<Subject> subjectList = null;
        try{
            transaction = session.beginTransaction();
            subjectList = session.getNamedQuery(GET_ALL_SUBJECTS_NAME_QUERY).list();
            transaction.commit();
        }  catch (HibernateException e) {
            if (transaction != null)
                transaction.rollback();
            logger.error(SQL_EXCEPTION_IN_QUERY, e);
            throw new DAOException(SQL_EXCEPTION_IN_QUERY, e);
        }
        return subjectList;
    }

// Generic service interface
public interface ITestSystemService<T> extends Serializable{

    List<T> getAll() throws DAOException;
}

//Service realization
@Service("subjectService")
@SessionScoped
public class SubjectServiceImpl implements ISubjectService{

    private static final long serialVersionUID = 1L;

    @Autowired
    @Qualifier("subjectDAO")
    private IDao<Subject> subjectDAO;

    public void setSubjectDAO(IDao<Subject> subjectDAO) {
        this.subjectDAO = subjectDAO;
    }

    @Override
    public List<Subject> getAll() throws DAOException {
        return subjectDAO.getAll();
    }

}

ビュースコープを備えた私のJSF Beanコントローラーでは、この構造で毎回問題が発生します。

アプリケーションの構造で何を変更する必要がありますか?

4

1 に答える 1

1

あなたが書いたものに次の変更を加えます。

SubjectServiceImpl

  • これはシングルトン スコープである可能性があります。サービスには状態がありません。
  • サブジェクトDAOのセッターは必要ありません(コンストラクターインジェクションを使用して、サブジェクトDAOを最終的にします。
  • getAll メソッド @Transaction を作成します(質問で回避したように)-これにより、Spring が Hibernate セッションを実行スレッドにバインドすることが保証されます。これは、SessionFactory#getCurrentSession() を使用して利用できます。

件名HibernateDAO

  • transaction = session.beginTransaction() など、トランザクションに関係するコードを削除します。セッションのプロビジョニングは、サービス メソッドの @Transactional アノテーションによって処理されます。
  • すべてのロールバック コードを削除する
  • DAO シングルトンのスコープを設定します - ここでも状態はありません。最終的な SessionFactory 変数に依存する必要があります。
  • コンストラクターを介して SessionFactory を注入します (フィールド注入は適切ではありません)。

上記のすべてを実行すると、問題が解消されることがあります (質問からは、実際の問題が何であるかは明らかではありません)。コードの最大の問題は、手動トランザクションと SessionFactory#getCurrentSession() の使用が混在していることです。

Spring 構成を提供していませんが、@Transactional を使用するには、Spring でトランザクション プロキシ動作を有効にする必要があります。@EnableTransactionManagement を使用して注釈を使用して、xml でこれを行うことができます。

于 2012-11-23T16:41:03.417 に答える