3

Hibernate 4 と Spring 3.1 を使用。起動して実行しているだけなので、これは私の理解不足かもしれません。DAO クラスのメソッドを呼び出して Hibernate を使用してデータを取得する Service クラスのメソッドがあります。Service メソッドに @Transactional のアノテーションを付けましたが、DAO メソッドで getCurrentSession を呼び出すとエラーが発生します。DAO メソッドに @Transactional のアノテーションを付けると、データは正常に取得されます。理由はわかりませんが、Service メソッドの @Transactional アノテーションが Hibernate セッションを作成し、それをスレッドにバインドし、getCurrentSession が呼び出されたときにこのセッションが DAO クラスに返されると考えていたでしょう。なぜこれが当てはまるのか、または私が何か間違ったことをしているのであれば、誰かが説明できますか?

root-context.xml:

<tx:annotation-driven transaction-manager="transactionManager"/>

サービス クラス:

public class BlahServiceImpl implements BlahService {

    @Transactional  
    public Blah GetMostRecentBlah() {
        BlahDAO blahDAO = DAOFactory.GetBlahDAO();
        return blahDAO.GetMostRecentBlah();
    }
}

DAO クラス:

private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

public Blah GetMostRecentBlah() {
    return (Blah)sessionFactory.getCurrentSession().createQuery("from Blah where blahID = (select max(blahID) from Blah)").uniqueResult();
}

エラー:

org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1039)
com.blah.blah.DAO.BlahDAOImpl.GetMostRecentBlah(BlahDAOImpl.java:18)

私が言ったように、@Transactioanl (および Service メソッド) で DAO 関数に注釈を付けると、これは機能しますが、その理由がわかりません。

4

2 に答える 2

3

2つの考えられる原因がそれ自体を示唆しています。

1)サービスBeanは、アノテーション駆動型トランザクションが有効になっていない別のApplicationContextにあります。

2)プロキシされた、つまりトランザクションのインスタンスではなく、生のインスタンスであるサービスのインスタンスへの参照を取得しています。

どちらが問題であるか、または他の問題であるかどうかを判断するには、サービスBeanが作成される原因となるコンテキストファイルを表示し、サービスのインスタンスを取得しているコードを表示します。

于 2012-05-30T03:45:05.523 に答える
1

解決策は次のとおりです。

<tx:annotation-driven proxy-target-class="true"  transaction-manager="transactionManager" />

クラスはプロキシされないため。

それ以外の場合、(私が直面したように) プライベート メソッドをトランザクションとしてプロキシする必要がある場合、cglib の代わりに aspectj を追加することになり、次の構成が役立つ場合があります。

 <!-- switches on the load-time weaving -->
    <context:load-time-weaver />

    <!--  proxies classes with aspectj and you may have @Transaction annotations for managing transactions-->    
    <tx:annotation-driven proxy-target-class="true"   mode="aspectj" transaction-manager="transactionManager" />

その後、jvm引数でサーバーを起動します

-javaagent:/path-to/spring-instrument-{spring-version}.jar
于 2013-01-12T15:07:51.023 に答える