是否有可能在Spring Boot中集成Spring托管的Hibernate拦截器(http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch14.html)?
我正在使用Spring Data JPA和Spring Data REST,并且需要一个Hibernate拦截器来对实体上的特定字段进行更新 .
使用标准JPA事件,不可能获得旧值,因此我认为我需要使用Hibernate拦截器 .
是否有可能在Spring Boot中集成Spring托管的Hibernate拦截器(http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch14.html)?
我正在使用Spring Data JPA和Spring Data REST,并且需要一个Hibernate拦截器来对实体上的特定字段进行更新 .
使用标准JPA事件,不可能获得旧值,因此我认为我需要使用Hibernate拦截器 .
8 回答
有完全由Hibernate管理的's not a particularly easy way to add a Hibernate interceptor that is also a Spring Bean but you can easily add an interceptor if it' . 为此,请将以下内容添加到
application.properties
:如果你需要Interceptor也是一个bean,你可以创建自己的
LocalContainerEntityManagerFactoryBean
. 来自Spring Boot 1.1.4的EntityManagerFactoryBuilder
对属性的泛型有点过于严格,所以你需要转换为(Map)
,我们将看看为1.2修复它 .以几个线程为参考,我得到了以下解决方案:
我正在使用Spring-Boot 1.2.3.RELEASE(这是目前的ga)
我的用例是this bug (DATAREST-373)中描述的 .
我需要能够在 create 上编码
User
@Entity
的密码,并在 save 上有特殊逻辑 . 使用@HandleBeforeCreate
创建非常简单,并检查@Entity
id是否为0L
相等 .为了保存,我实现了Hibernate Interceptor,扩展了EmptyInterceptor
使用spring boot文档说明了这一点
正如许多参考文献所述,我们可以在Spring-Boot配置中使用
spring.jpa.properties.hibernate.ejb.interceptor
定义我们的拦截器 . 但是我无法让@Autowire PasswordEncoder
工作 .所以我求助于使用HibernateJpaAutoConfiguration并覆盖
protected void customizeVendorProperties(Map<String, Object> vendorProperties)
. 这是我的配置 .自动装配
Interceptor
而不是允许Hibernate实例化它是使其工作的关键 .现在困扰我的是逻辑被分成两部分,但希望一旦DATAREST-373被解决,那么这就不必要了 .
我简单的一个用于spring boot的hibernate监听器的文件示例(spring-boot-starter 1.2.4.RELEASE)
我在Spring 4.1.1,Hibernate 4.3.11应用程序中遇到了类似的问题 - 而不是Spring Boot .
我发现(在阅读Hibernate EntityManagerFactoryBuilderImpl代码之后)的解决方案是,如果将bean引用而不是类名传递给实体管理器定义的
hibernate.ejb.interceptor
属性,Hibernate将使用已经实例化的bean .所以在我的应用程序上下文中的entityManager定义中我有这样的东西:
auditInterceptor由Spring管理,因此可以使用自动装配和其他Spring-natured行为 .
在研究了如何将Hibernate Interceptor与Spring Data JPA集成两天后,我找到了另一种方法,我的解决方案是java配置和xml配置之间的混合,但this post非常有用 . 所以我的最终解决方案是:
AuditLogInterceptor类:
数据源Java配置:
添加拦截器的实体和事务管理器
持久性配置文件
Hello ,
给它一个读:https://github.com/spring-projects/spring-boot/commit/59d5ed58428d8cb6c6d9fb723d0e334fe3e7d9be(使用:HibernatePropertiesCustomizer接口)
OR
对于简单的拦截器:
要在您的应用程序中进行配置,您只需添加: spring.jpa.properties.hibernate.ejb.interceptor = path.to.interceptor (在application.properties中) . 拦截器本身应该是 @Component .
只要拦截器实际上不使用任何bean . 否则它会有点复杂,但我很乐意提供解决方案 .
不要忘记在application-test.properties中添加一个 EmptyInterceptor ,以便在测试中不使用日志系统(或任何你想要用它的东西)(这不是很有用) .
希望这对你有用 .
最后一点: always update your Spring / Hibernate versions (尽可能使用最新版本),您会发现大多数代码都会变得多余,因为新版本会尽可能地减少配置 .
我遇到了同样的问题,并创建了一个小 spring 库来处理所有的设置 .
https://github.com/teastman/spring-data-hibernate-event
如果您使用的是Spring Boot,则只需添加依赖项:
然后将注释@HibernateEventListener添加到第一个参数是您要侦听的实体的任何方法,第二个参数是您要监听的Hibernate事件 . 我也是添加了静态util函数getPropertyIndex,以便更轻松地访问要检查的特定属性,但您也可以查看原始Hibernate事件 .
因为拦截器没有注册为spring bean,所以可以使用一个可以得到
ApplicationContext
实例的util,如下所示:然后你可以在拦截器中调用服务,如下所示: