The introduction

I recently discovered that I was wrong to assume that Hibernate is independent of Spring and that Hibernate interceptors and listeners cannot inject Spring container objects.

Hibernate can inject Spring container objects, but it is the creation order of Repository that makes the object injection fail.

example

The original conclusion

The User entity:

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

}

Entity listener:

@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); }}

Execute the method to save the user and print the result:

null
null
null
null

So I mistakenly concluded that Hibernate is independent of Spring and cannot use objects in the Spring container.

Dependency injection

Modify the listener to remove the repository dependencies, including removing the UserRepository that is directly dependent on the repository and the UserService that is indirectly dependent on the repository.

@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); }}

Then execute the save user method, and the result is as follows:

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

Updated previous erroneous opinion:

HibernateThe listener and interceptor are not independent
SpringIf the repository is directly or indirectly dependent, all object injections will fail because of the order in which they are created. Objects can be injected successfully if they are not dependent on the repository.

The solution

So there are two options for manipulating the database in Hibernate:

The first is our old ApplicationContextHolder, where the static method gets the context and the repository object is manually retrieved.

The second option, based on this new discovery, is to inject the JDBCTemplate for database manipulation.

conclusion

Although the wrong conclusion I summarized does not affect the daily use, I think it is necessary to correct it. Everyone will be excellent technicians and architects in the future. I don’t want to make everyone encounter difficulties on the road of growth because of my wrong conclusion.