2011-02-04 5 views
5

私のカスタム認証プロバイダでは、サービスAPIを使用してドメインオブジェクトを取得できましたが、あるドメインオブジェクトから別のドメインオブジェクトにクロールして、トランザクションを持つSpringセキュリティカスタム認証プロバイダをラップする

domain.getAnotherDomain().getProperty(); // epic FAIL 

私はトランザクションにすべての私のプロジェクトのAPIをラップするために、次のAOPのトランザクションを持っている、と私は私のカスタム認証プロバイダは、次のパターンに陥るかなり確信している: - - :

Hibernateセッションが存在しない文句を言い
<tx:advice id="txAdvice"> 
    <tx:attributes> 
     <tx:method name="*" propagation="REQUIRED" /> 
    </tx:attributes> 
</tx:advice> 

<aop:config> 
    <aop:advisor pointcut="execution(* my.project..*.*(..))" advice-ref="txAdvice" /> 
</aop:config> 

OpenSessionInViewフィルタも設定しましたが、とにかくSpring Securityには当てはまりません。

私は、すべての必要なチェックを実行するための特定のサービスAPIを作成することができますが、私は私のカスタム認証プロバイダを適切なトランザクションでラップできないのが不思議です。

説明はありますか?ありがとう。

答えて

2

私の回避策のソリューションは、カスタム認証プロバイダの遅延読み込みエラーを回避するためのチェックを実行するサービスAPIを作成することです。

1

春は、Hibernateのセッションが存在していない文句を言い

ない私はすべてのあなたの質問に従いますが、私は上記のステートメントは、右、あなたの主な問題を表していると思いますかなり確実?あなたは、任意のスタックトレースを提供していませんでしたが、私は、これはあなただけ説明したシナリオの典型的な悪名高い「何のセッションまたはセッション閉じて」、ではない想像:。

domain.getAnotherDomain()のgetProperty(); //エピックFAIL

たぶん私は何かが足りないんだけど、私は典型的な答えはここにも適用されることになると思う:セッションがすでにあるとき、あなたは怠惰な負荷にそれを持っていないように、fetch=FetchType.EAGERとの関係をマップ閉まっている。

+0

例外メッセージは、「ss.domainロールのコレクションを遅延して初期化できませんでした。セッションまたはセッションが閉じられませんでした。私は、絶対的な必要がない限り、eager fetchingを実行しない方がいいです...つまり、カスタム認証プロバイダクラスをラップするトランザクションを取得した場合です。 – limc

+0

もし、 'domain'をあるセッションに読み込むと、別のセッションで' domain'から 'anotherDomain'を遅延ロードすることができなくなります。私はこれがあなたのケースであるかどうかはわかりませんが(あなたの質問から私には分かりません)。しかし、常にEagerの読み込みをしたくない場合は、Fetch Profilesを使用することを検討することもできますが、時には必要があることを知っています。 – jpkrohling

0

同じ問題が発生しました。その原因は、web.xmlファイルのOpenSessionInViewフィルタの前にSpring Securityのフィルタが宣言されていたためです。私はそれらを交換した後、問題は遠ざかった。

理由は、HibernateセッションがOpenSessionInViewフィルタによって開かれる前にSpringセキュリティが呼び出されているために、セッションが開かれていないからです。

0

あなたが意味のある提案をするためのコードを掲載していません。

しかし、カスタム認証プロバイダの1つの問題は、あなたが上書きして抽象クラスインスタンスから呼び出されている抽象メソッド@Transactionalとしてマークされている可能性があります。 AbstractUserDetailsAuthenticationProvider から例えばについて

retreiveUser。このメソッドはインスタンス内から呼び出されます(メソッドを認証する)ので、AOPプロキシメカニズムを使用してトランザクションを初期化することはできません。詳細については、@Transactional method calling another method without @Transactional anotation?

のAOPプロキシを使用してください。 AOPプロキシはトランザクションの作成を担当します。 AOPプロキシは、インスタンス内のメソッドがインスタンスの外側から呼び出された場合にのみアクティブになります。

関連する問題