Spring MVC コントローラーで JPA 遅延読み込みを使用します (ただし、カジュアルなサーブレットである可能性があります)。Author と @ManyToOne 遅延関係を持つ Book エンティティを見つけました。
@Entity
public class Book extends BaseEntity {
private String isbn;
private String title;
@ManyToOne(fetch= FetchType.LAZY)
private Author author;
private int price;
SpringMVC コントローラーはそれを検索します (例のためにコードを簡略化しました)。
@Controller
public class EditBookController {
@Autowired BookDao bDao;
@RequestMapping(value={"/updatebook"})
public String updateBook(@RequestParam("id")Long id) {
Book book = bDao.find(id);
System.out.println( book.getAuthor().getFirstName() ); // Lazy loading FAIL
return “bookView”;
}
BookDao.find() は、その祖先の BaseRepository で定義されています。
@Transactional
@SuppressWarnings("unchecked")
public class BaseRepository<E extends BaseEntity> {
Class entityClass;
public E find(Long id){
return ( E ) em.find( entityClass, id );
}
もちろん、コントローラーで LazyInit 例外をトリガーします。そこで、フィルター OpenEntityManagerInViewFilter を追加すると、正常に動作します。ブック エンティティは、コントローラーで切り離されなくなりました。
ここで、コントローラーのブックを変更したいと思います。たとえば、book.setPrice(4); を呼び出します。
@RequestMapping(value={"/updatebook"})
public String updateBook(@RequestParam("id")Long id) {
Book book = bDao.find(id);
System.out.println( book.getAuthor().getFirstName() ); // Lazy loading OK
book.setPrice(4);
return “bookView”;
}
私は、Hibernate がダーティー チェックを行い、本の値が変更されたことを検出して保存することを期待していました。EntityMangager を閉じるときに、OpenEntityInViewFilter によってトリガーされます。
しかし、明示的に em.merge(book) を呼び出さない限り、(デタッチされていない) 管理対象エンティティは DB への更新をトリガーしません。
この場合、ダーティチェックがアクティブでない理由を誰かに説明してもらえますか? どうもありがとう!
春 v3.1.2 休止状態 v4.1.4