Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么OpenEntityManagerInViewFilter不执行脏检查?_Java_Hibernate_Jpa_Spring Mvc - Fatal编程技术网

Java 为什么OpenEntityManagerInViewFilter不执行脏检查?

Java 为什么OpenEntityManagerInViewFilter不执行脏检查?,java,hibernate,jpa,spring-mvc,Java,Hibernate,Jpa,Spring Mvc,我在SpringMVC控制器中使用JPA延迟加载,但它可能是一个临时servlet。我发现一个图书实体与作者有着@manytone惰性关系 @Entity public class Book extends BaseEntity { private String isbn; private String title; @ManyToOne(fetch= FetchType.LAZY) private Author author; private int

我在SpringMVC控制器中使用JPA延迟加载,但它可能是一个临时servlet。我发现一个图书实体与作者有着@manytone惰性关系

@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在其祖先库中定义:

@Transactional
@SuppressWarnings("unchecked")
public class BaseRepository<E extends BaseEntity> {
    Class entityClass;

    public E find(Long id){
        return ( E ) em.find( entityClass, id );
    }
我希望Hibernate进行脏检查,检测到该书的值已更改,然后保存它。它将在关闭EntityManager时由OpenEntityInViewFilter触发

但我的非分离托管实体不会触发对数据库的更新,除非我明确地调用em.mergebook

有人能给我解释一下为什么在这种情况下脏检查不起作用吗? 非常感谢

Spring v3.1.2
Hibernate v4.1.4

您使用什么来管理事务

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


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

谢谢Augusto。我已经在控制器级别EditBookController添加了@Transactional,但实体仍然没有保存。还有别的想法吗?
@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”;
}