使用 Spring IoC 来管理 Hibernate 拦截器
Use Spring IoC to manage Hibernate Interceptor
我正在使用 Spring Boot v2.0.3 和 Hibernate 5.2。我想创建一个 Hibernate 拦截器,以在我的实体字段之一中生成一个值,基于我的数据库中的一个唯一数字,在它被保存之前。
我获取了一些在线资源,最后扩展了 Hibernate EmptyInterceptor 以覆盖 onSave 方法。
@Component
public class CustomInterceptor extends EmptyInterceptor {
private final TicketService ticketService;
@Autowired
public CustomInterceptor(TicketService ticketService) {
this.ticketService = ticketService;
}
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
if (entity instanceof Ticket) {
if (((Ticket) entity).getNumTicket() == null) {
String pharmacyId = ((Ticket) entity).getEtablishmentId();
Long newTicketNumber = ticketService.findMaxNumTicketForEtablishment(etablishmentId);
// ((Ticket) entity).setNumTicket((newTicketNumber != null ? newTicketNumber : 1));
for ( int i = 0; i < propertyNames.length; i++ ) {
if ( "numTicket".equals( propertyNames[i] ) ) {
state[i] = newTicketNumber;
return true;
}
}
return true;
}
}
return false;
}
}
在我的 application.yml 配置文件中,我添加了以下键:
spring.jpa.properties.hibernate.ejb.interceptor: com.mycompany.xxx.utils.CustomInterceptor
当我尝试保存票证时,我可以看到方法 onSave 被正确调用,但是由于拦截器完全由 Hibernate 实例化,它不在 Spring bean 上下文中,所以我不能使用@Autowire 注释。 (所以我的 ticketService 是空的)。
在旧主题 (How to use Spring managed Hibernate interceptors in Spring Boot?) 中,我看到有人试图覆盖 HibernateJpaAutoConfiguration 供应商属性,但它不再可用。
我在 Github 上发现了这个问题: https://github.com/spring-projects/spring-boot/issues/11211 ,完美地说明了我的问题,但我无法成功使其工作(也尝试创建一个 HibernatePropertieCustomizer,但我没有使用它)。
如果有人能指出我正确的方向,我将不胜感激。谢谢
I found this issue on Github : https://github.com/spring-projects/spring-boot/issues/11211 , perfectly illustrating my problem,
我完全不确定 #11211 是如何关联的,因为您报告了一个问题,试图在由 Hibernate 管理的组件中使用依赖注入。
首先,您要向 Hibernate 注册一个 class(不是 bean),因此添加 @Component
不是一个好主意,因为 Hibernate 现在负责实例化您的 class .如果你添加 @Component
看起来你希望组件扫描来处理这个对象(而实际上,Hibernate 将根据你在配置中提供的 FQN 来处理它)。
然后,Hibernate 添加了一种方法来自定义此类实例化的发生方式,并且 Spring 从 #13717 开始,默认情况下引导自动配置一个 SpringBeanContainer
,它在 [=24] 中可用=] 仅启动 2.1.x
。如果你想能够使用常规的依赖注入,你需要升级到 Spring Boot 2.1.
我正在使用 Spring Boot v2.0.3 和 Hibernate 5.2。我想创建一个 Hibernate 拦截器,以在我的实体字段之一中生成一个值,基于我的数据库中的一个唯一数字,在它被保存之前。
我获取了一些在线资源,最后扩展了 Hibernate EmptyInterceptor 以覆盖 onSave 方法。
@Component
public class CustomInterceptor extends EmptyInterceptor {
private final TicketService ticketService;
@Autowired
public CustomInterceptor(TicketService ticketService) {
this.ticketService = ticketService;
}
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
if (entity instanceof Ticket) {
if (((Ticket) entity).getNumTicket() == null) {
String pharmacyId = ((Ticket) entity).getEtablishmentId();
Long newTicketNumber = ticketService.findMaxNumTicketForEtablishment(etablishmentId);
// ((Ticket) entity).setNumTicket((newTicketNumber != null ? newTicketNumber : 1));
for ( int i = 0; i < propertyNames.length; i++ ) {
if ( "numTicket".equals( propertyNames[i] ) ) {
state[i] = newTicketNumber;
return true;
}
}
return true;
}
}
return false;
}
}
在我的 application.yml 配置文件中,我添加了以下键:
spring.jpa.properties.hibernate.ejb.interceptor: com.mycompany.xxx.utils.CustomInterceptor
当我尝试保存票证时,我可以看到方法 onSave 被正确调用,但是由于拦截器完全由 Hibernate 实例化,它不在 Spring bean 上下文中,所以我不能使用@Autowire 注释。 (所以我的 ticketService 是空的)。
在旧主题 (How to use Spring managed Hibernate interceptors in Spring Boot?) 中,我看到有人试图覆盖 HibernateJpaAutoConfiguration 供应商属性,但它不再可用。
我在 Github 上发现了这个问题: https://github.com/spring-projects/spring-boot/issues/11211 ,完美地说明了我的问题,但我无法成功使其工作(也尝试创建一个 HibernatePropertieCustomizer,但我没有使用它)。
如果有人能指出我正确的方向,我将不胜感激。谢谢
I found this issue on Github : https://github.com/spring-projects/spring-boot/issues/11211 , perfectly illustrating my problem,
我完全不确定 #11211 是如何关联的,因为您报告了一个问题,试图在由 Hibernate 管理的组件中使用依赖注入。
首先,您要向 Hibernate 注册一个 class(不是 bean),因此添加 @Component
不是一个好主意,因为 Hibernate 现在负责实例化您的 class .如果你添加 @Component
看起来你希望组件扫描来处理这个对象(而实际上,Hibernate 将根据你在配置中提供的 FQN 来处理它)。
然后,Hibernate 添加了一种方法来自定义此类实例化的发生方式,并且 Spring 从 #13717 开始,默认情况下引导自动配置一个 SpringBeanContainer
,它在 [=24] 中可用=] 仅启动 2.1.x
。如果你想能够使用常规的依赖注入,你需要升级到 Spring Boot 2.1.