【问题标题】:Why OpenEntityManagerInViewFilter does not perform dirty-checking?为什么 OpenEntityManagerInViewFilter 不执行脏检查?
【发布时间】:2012-08-03 14:42:32
【问题描述】:

我在 Spring MVC 控制器中使用 JPA 延迟加载(但它可能是一个临时的 servlet)。我发现一个 Book 实体与 Author 具有 @ManyToOne 惰性关系。

@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)。

有人可以向我解释一下为什么在这种情况下脏检查没有激活吗? 非常感谢!

春天 v3.1.2 休眠 v4.1.4

【问题讨论】:

    标签: java hibernate jpa spring-mvc


    【解决方案1】:

    您使用什么来管理交易?

    如果 spring 正在管理它们,那么您需要在控制器方法中添加 @Transactional。 @Transactional 注释用于划分事务的开始位置,因此您遇到的问题是 spring/hibernate 不知道在 updateBook() 返回时需要保留任何更改。 OpenEntityManagerInViewFilter 不提交事务(但您可能想编写自己的实现来进行提交)。

    在我看来(其他人可能不同意),使用 @Transactional 注释应用程序的入口点是一种很好的做法,它们可能是控制器、JMS 使用者或其他任何东西。

    【讨论】:

    • 谢谢奥古斯托。我在控制器级别(EditBookController)添加了@Transactional,但实体仍未保存。还有其他想法吗?
    猜你喜欢
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多