纠正一个 Hibernate 的错误结论

引言

以前一直觉得Hibernate独立于SpringHibernate相关的拦截器、监听器都不能注入Spring容器对象,最近发现这个观点是错误的。java

Hibernate能够注入Spring容器对象,只是repository的建立顺序缘由,使得对象注入失败。spring

例子

原结论

User实体:数据库

@Entity
@EntityListeners(PasswordEncodeListener.class)
public class User {

}

实体监听器:架构

@Component
public class PasswordEncodeListener {

    @Autowired
    private UserRepository repository;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private NoRepoService noRepoService;

    @PrePersist
    public void encode(User user) {
        System.out.println(repository);
        System.out.println(jdbcTemplate);
        System.out.println(userService);
        System.out.println(noRepoService);
    }
}

执行保存用户的方法,打印结果:code

null
null
null
null

因此以前得出了错误的结论,认为Hibernate独立于Spring,没法使用Spring容器内的对象。对象

依赖注入

修改监听器,去除对仓库的依赖,包括去除直接依赖仓库的UserRepository与间接依赖仓库的UserServiceit

@Component
public class PasswordEncodeListener {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private NoRepoService noRepoService;

    @PrePersist
    public void encode(User user) {
        System.out.println(jdbcTemplate);
        System.out.println(noRepoService);
    }
}

再执行保存用户的方法,结果以下:io

org.springframework.jdbc.core.JdbcTemplate@7e9f2c32
club.yunzhi.jpa.service.NoRepoServiceImpl@3976ebfa

更新以前的错误观点:class

Hibernate的监听器、拦截器并非独立于 Spring的,而是由于若是直接或间接依赖了仓库,由于建立的顺序问题,会致使全部对象注入失败。若是不依赖于仓库,对象能够注入成功。

解决方案

因此在Hibernate内操做数据库就有了两种方案:容器

第一种就是咱们过去的ApplicationContextHolder,静态方法获取context,手动获取仓库对象。

第二种方案就是基于此次的新发现,能够注入JdbcTemplate,进行数据库的操做。

总结

虽然我总结的错误结论并不影响平常的使用,可是认为仍是有必要进行纠正,你们之后都会是优秀的技术员、架构师,不但愿由于个人一个错误结论,让你们在之后成长的道路上遇到困难。