1

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

4

1 に答える 1

0

トランザクションを管理するために何を使用していますか?

Spring がそれらを管理している場合は、コントローラー メソッドに @Transactional を追加する必要があります。@Transactional アノテーションは、トランザクションの開始場所を区別するために使用されるため、Spring/Hibernate は、返されたときに変更を永続化する必要があることを認識していないという問題がありupdateBook()ます。OpenEntityManagerInViewFilter はトランザクションをコミットしません (ただし、コミットを行う独自の実装を作成したい場合があります)。

私の見解では (他の人は同意しないかもしれません)、アプリケーションのエントリ ポイントに @Transactional でアノテーションを付けることをお勧めします。それらは、コントローラ、JMS コンシューマ、またはその他のものである可能性があります。

于 2012-08-03T14:49:42.463 に答える