我在Hibernate 5.2中使用Spring Boot v2.0.3。我想创建一个Hibernate Interceptor,以便在保存之前根据数据库中的唯一编号在我的实体字段之一中生成一个值。
我获取了一些在线资源,并最终将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为null)。
在一个旧主题(How to use Spring managed Hibernate interceptors in Spring Boot?)中,我看到有人试图覆盖HibernateJpaAutoConfiguration供应商属性,但现在不再可用。
我在Github上发现了这个问题:https://github.com/spring-projects/spring-boot/issues/11211,完美地说明了我的问题,但我无法成功使其工作(也尝试创建HibernatePropertieCustomizer,但我无法使用它)。
如果有人能指出我正确的方向,我将不胜感激。谢谢
答案 0 :(得分:0)
我在Github上发现了这个问题:https://github.com/spring-projects/spring-boot/issues/11211,完美地说明了我的问题,
我不确定#11211是如何关联的,因为您报告了在Hibernate管理的组件中尝试使用依赖项注入时遇到的问题。
首先,您要向Hibernate注册一个类(不是Bean),所以添加@Component
并不是一个好主意,因为Hibernate现在负责实例化您的类。如果添加@Component
,则似乎希望组件扫描能够处理该对象(实际上,Hibernate将根据您在配置中提供的FQN对其进行处理)。
然后,Hibernate添加了一种自定义此类实例化方式的方法,并且默认情况下,Spring Boot自#13717起自动配置SpringBeanContainer
,仅在Spring Boot 2.1.x
中可用。如果您希望能够使用常规的依赖项注入,则需要升级到Spring Boot 2.1。