【问题标题】:Use Spring IoC to manage Hibernate Interceptor使用 Spring IoC 管理 Hibernate Interceptor
【发布时间】:2019-05-20 02:22:21
【问题描述】:

我正在使用带有 Hibernate 5.2 的 Spring Boot v2.0.3。我想创建一个 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

当我尝试保存 Ticket 时,我可以看到 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,但我没有使用它)。

如果有人能指出我正确的方向,我将不胜感激。谢谢

【问题讨论】:

    标签: hibernate spring-boot dependency-injection interceptor


    【解决方案1】:

    我在 Github 上发现了这个问题:https://github.com/spring-projects/spring-boot/issues/11211,完美地说明了我的问题,

    我完全不确定 #11211 是如何相关的,因为您报告了在 Hibernate 管理的组件中尝试使用依赖注入的问题。

    首先,您正在向 Hibernate 注册一个类(不是 bean),因此添加 @Component 不是一个好主意,因为 Hibernate 现在负责实例化您的类。如果你添加@Component,看起来你希望组件扫描来处理这个对象(事实上,Hibernate 会根据你在配置中提供的 FQN 来处理它)。

    然后,Hibernate 添加了一种方法来自定义这种实例化的发生方式,并且 Spring Boot 默认自动配置一个 SpringBeanContainer,从 #13717 开始,它仅在 Spring Boot 2.1.x 中可用。如果希望能够使用常规的依赖注入,则需要升级到 Spring Boot 2.1。

    【讨论】:

    • 在问题的原始帖子中,RizziCR 写道“可以将拦截器添加为属性“spring.jpa.properties.hibernate.session_factory.interceptor”,但这是一个休眠实例,无法访问在春天的背景下。”。这基本上就是我在这篇文章中描述的问题。无论如何,谢谢您的回答,我必须尽快升级Spring。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2011-09-19
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多