Hibernateの遅延読み込みエラーがロールのコレクションを遅延初期化できませんでした
Hibernate Lazy Loading Error Failed Lazily Initialize Collection Role
[b]転載元:http://www.qingsoft.cn/viewthread.php?tid = 1175 [/ b]
ユーザーと役割
ユーザーuserがロールを設定しました= new hashset(0)
ユーザーでロールコレクションを取得すると、次の例外が発生します。
Javaコード
* org.hibernate.lazyinitializationexception: failed to lazily initialize a collection of role: com.demo.security.entity.user.roles, no session or session was closed
1.当時の私の解決策は次のとおりでした。
userdaoimpl.java
Javaコード
* @suppresswarnings('unchecked')
* public list queryall(final integer isinitialize) {
*
* return gethibernatetemplate().executefind(new hibernatecallback(){
* public object doinhibernate(session session)
* throws hibernateexception, sqlexception {
* query q = session.createquery('from user u left join fetch u.userinfo')
* if(isinitialize == 0) return q.list()
* else{
* list users = q.list()
* for(user user : users){
* if(isinitialize ==1)
* gethibernatetemplate().initialize(user.getroles())
* }
* return users
* }
* return q.list()
* }})
* }
このように書くのは面倒で、効率が良くないと感じます。
2.インターネット上にlazy = falseがあることを確認すると、これは休止状態の注釈にも当てはまります(赤い部分に注意してください)。
Javaコード
* @manytomany(
* targetentity = role.class,
* cascade = {cascadetype.persist, cascadetype.merge},
* fetch = fetchtype.eager)
* @jointable(
* name = 'user_role',
* joincolumns = {@joincolumn(name = 'user_id')},
* inversejoincolumns = {@joincolumn(name = 'role_id')})
* @cache(usage = cacheconcurrencystrategy.read_write)
* public set getroles() {
* return roles
* }
もしそうなら、効率はさらに悪くなります(特定のデータが必要かどうかにかかわらず、それは照会されます、それは無駄です)
最後に記事を読んでください:
フィルタを使用してすべてのリンクをフィルタリングすることです
フィルタを使用する場合は、トランザクションを設定する必要があります。そうしないと、セッションは読み取り専用になり、変更または削除できません。
web.xml
Xml/html code
*
* hibernatefilter
*
* org.springframework.orm.hibernate3.support.opensessioninviewfilter
*
*
*
*
* hibernatefilter
* *.action
*
上記のfetch = fetchtype.eagerはfetch = fetchtype.lazyに変更されます
これは次のように説明されます。
Springは、私たちにとって最も頭痛の種の1つである、休止状態のセッションのシャットダウンと開始の問題を解決します。
Hibernateでは、関連するオブジェクトとプロパティの遅延読み込みが可能ですが、遅延読み込みが同じHibernateセッションに制限されることを保証する必要があります。サービスレイヤーが遅延読み込みが有効になっているドメインオブジェクトをWeb層に返す場合、Web層が遅延読み込みが必要なデータにアクセスすると、ドメインオブジェクトを読み込む休止状態のセッションが閉じられ、遅延読み込みデータへのアクセスが次のようになります。異常な。 Springが提供するopensessioninviewfilterは、この問題を非常にうまく解決します。 opensessioninviewfilterの主な機能は、各リクエストプロセスを休止状態のセッションにバインドすることです。最初のトランザクションが完了している場合でも、Webレイヤーで遅延読み込みを実行することもできます。 opensessioninviewfilterフィルターは、休止状態のセッションを要求スレッドにバインドします。要求スレッドは、Springのトランザクションマネージャーによって自動的に検出されます。したがって、opensessioninviewfilterは、サービス層がトランザクション管理にhibernatetransactionmanagerまたはjtatransactionmanagerを使用する環境に適用でき、非トランザクションの読み取り専用データ操作にも使用できます。
要求->セッションを開く->接続を開く、トランザクションを開始する->永続的な操作->レンダリング(接続を閉じる、セッション)->応答
これらのプロセスの一部は省略されており、あまり関係ありません。