我在 Spring MVC 控制器中使用 JPA 延迟加载(但它可能是一个临时的 servlet)。我找到了一个与 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)。
有人可以向我解释为什么在这种情况下脏检查不活跃吗?非常感谢!
Spring v3.1.2 休眠 v4.1.4