2013-03-05 1 views
6

私はかなり奇妙な問題があるようです。ユーザーとその役割をJSPで表示します。何らかの理由で、ロールはページが初めてロードされたときにのみ表示されます。私はページをリフレッシュし、役割はすべてデータベースから削除されます!私が行ったすべてがリストであるときにHibernateがコレクションのエントリを削除するのはなぜですか?

私の設定は標準のSpring MVC、JPA + Hibernate(Spring Data)アプリケーションです。以下に示すように

@Entity 
public class User { 
    @Id 
    @GeneratedValue 
    private int id; 

    private String name; 

    @ManyToMany 
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) 
    private Set<Role> roles = new HashSet<>(); 
} 

@Entity 
public class Role { 
    @Id 
    private String id; 

    private String name; 
} 

私はない春データリポジトリを有する(セッターとゲッターを想定)UserRole - 私は2つのエンティティを有する

を(スプリング3.2.xのは、4.1.8を休止します)余分なメソッドを定義します。

public interface UserRepository extends CrudRepository<User, Integer> { 
} 

私は、以下のような関連する方法を持つサービスとコントローラを持っています。

// service 
@Transactional(readOnly = true) 
public Iterable<User> findAll() { 
    return userRepository.findAll(); 
} 

// controller 
@RequestMapping 
public String showUsers(ModelMap model) { 
    model.put("users", userService.findAll()); 

    return "admin/users"; 
} 

私のJSPでは、すべてのユーザーと関連する役割を表示しようとしています。

<c:forEach var="user" items="${users}"> 
    <tr> 
     <td>${user.name}</td> 
     <td> 
      <c:forEach var="role" items="${user.roles}"> 
       ${role.name} 
      </c:forEach> 
     </td> 
    </tr> 
</c:forEach> 

私が先に言ったように、このページがレンダリングされた後、私のuser_roleテーブル内のレコードが削除されます。 org.hibernateためDEBUGを有効にすると、クエリログを有効にする際

は、ここで私は、ログで見つけたものです:

22:36:25 DEBUG Collection dereferenced: [com.adarshr.domain.User.roles#1] [Collections.java:76] 
22:36:25 DEBUG Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects [AbstractFlushingEventListener.java:117] 
22:36:25 DEBUG Flushed: 0 (re)creations, 0 updates, 1 removals to 1 collections [AbstractFlushingEventListener.java:124] 
22:36:25 DEBUG Deleting collection: [com.adarshr.domain.User.roles#1] [AbstractCollectionPersister.java:1124] 
22:36:25 DEBUG 
    delete 
    from 
     user_role 
    where 
     user_id=? [SqlStatementLogger.java:104] 
22:36:25 DEBUG Done deleting collection [AbstractCollectionPersister.java:1182] 

はっきり怪しい何かがここで起こっています。私のコレクションが最初に参照解除されるのはなぜですか?

ここに私のJPAエンティティマネージャファクトリの定義があります。

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="mainDataSource" /> 
    <property name="packagesToScan" value="com.adarshr.domain" /> 
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
    </property> 
    <property name="jpaProperties"> 
     <value> 
      hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 
      hibernate.format_sql=${hibernate.format.sql} 
      hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy 
      hibernate.show_sql=${hibernate.show.sql} 
      hibernate.enable_lazy_load_no_trans=true 
     </value> 
    </property> 
</bean> 

私はここで何かが分かりませんか?

+0

「enable_lazy_load_no_trans」はどこから取得しましたか?私が知ることができるのは、それがバギーであり、使用することは推奨されていないという人たちです。 –

+0

http://stackoverflow.com/questions/578433/how-to-solve-lazy-initialization-exception-using-jpa-and-hibernate-as-providerより – adarshr

+0

「慎重に使用することは控えめです!」 "これは実際にベンチマーク対象の機能にすぎません..." "...これは一般的な用途では本当に悪い考えです。" 「自己責任で使用する」。 "...可能性のある結果を知らずに人々が使用すべきだと思う機能ではない。" https://hibernate.onjira.com/browse/HHH-7457ええ、そこにテーマを感じていますか?それを使用しないでください。 –

答えて

5

投稿したコードが正しいと思われるので、私はここで推測しています。

私が提案する最初のことは、この初期設定(ロールが削除される唯一の場所だと思われます)を削除することです。それは一般的には良いアイデアですが(下のコメントを参照してください)、私はhibernate.enable_lazy_load_no_trans=true過去にleak connectionsに知られている:

private Set<Role> roles = new HashSet<>(); 

2回目の試行は、とどのような変更もmappedByを使用して多対多の関係の逆側に注釈を付けている場合かどうかを確認することです。

3つ目の試みは、FetchType、Hibernate.initialize()を使用して、問題を解決して問題を解決する(さらに多くの場合enable_lazy_load_no_transの位置を悪化させる)場合です。

最終1はenable_lazy_load_no_transを取り除くと使用取得されOpenSessionInView

EDIT:ああ、最後の一つは、あなたが*、それを持っていることがあり、このバグ(4.1.8および影響を受けた4.1.9を休止状態): https://hibernate.onjira.com/browse/HHH-7971

だから4.1でショットをしている。7は良い結果をもたらすかもしれません(あるいは悪いかもしれません)。

*「あなたのケースは非常に似ているため、あなたのコードをバグレポートのテストケースとして送信するように招待されています。

+0

悪い考え。 *コレクション型を常に空のコレクションに初期化します。私はこれが根本的な原因ではないことを保証します。 –

+0

@ Ryan Stewart私は、hibernate.enable_lazy_load_no_trans = trueを持つことが問題になるかもしれないと私は同意します。 –

+0

バグレポートを見ただけです。私はまったく同じ問題を抱えています。私はテストケースを送ろうとします。 4.1.7へのダウングレードは、問題を修正するように見えました。しかし、コレクションを初期化していても、違いはありませんでした。 OEMIVFilterを働かせても。 – adarshr

関連する問題