Используйте Spring IoC для управления Hibernate Interceptor - PullRequest
0 голосов
/ 19 декабря 2018

Я использую 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, он не находится в контексте bean-компонента Spring, поэтому я не могу использовать аннотацию @Autowire.(поэтому мой ticketService имеет значение null).

В старой теме ( Как использовать перехватчики Hibernate, управляемые Spring в Spring Boot? ), я вижу, что кто-то пытался переопределить свойства поставщика HibernateJpaAutoConfiguration,но он больше недоступен.

Я нашел эту проблему на Github: https://github.com/spring-projects/spring-boot/issues/11211, прекрасно иллюстрируя мою проблему, но я не смог успешно заставить ее работать (также пытался создать HibernatePropertieCustomizer, ноЯ не смог его использовать).

если кто-нибудь может указать мне правильное направление, я был бы признателен.спасибо

1 Ответ

0 голосов
/ 20 декабря 2018

Я обнаружил эту проблему на Github: https://github.com/spring-projects/spring-boot/issues/11211, отлично иллюстрирующую мою проблему,

Я не уверен, как вообще связан # 11211, поскольку вы сообщаете оПроблема при попытке внедрения зависимости в компонент, управляемый Hibernate.

Прежде всего, вы регистрируете класс (не bean-компонент) в Hibernate, поэтому добавление @Component не является хорошей идеей, поскольку Hibernateтеперь ответственность за создание экземпляра вашего класса.Если вы добавите @Component, похоже, вы ожидаете, что компонентное сканирование будет обрабатывать этот объект (в то время как Hibernate будет обрабатывать его в соответствии с FQN, указанным вами в конфигурации).

Затем Hibernate добавилспособ настроить, как происходит такое создание экземпляра, и Spring Boot автоматически настраивает SpringBeanContainer по умолчанию с # 13717 , который доступен только в Spring Boot 2.1.x.Если вы хотите использовать регулярное внедрение зависимостей, вам необходимо выполнить обновление до Spring Boot 2.1.

...