现在,我想将我的应用程序从Spring hibernate 3升级到5
在休眠3下,我创建了一个POST-COMMIT-INSERT | UPDATE | DELETE事件侦听器,如下所示
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
....
</list>
</property>
<property name="hibernateProperties">
<props>
....
</props>
</property>
<property name="eventListeners">
<map>
<entry key="post-commit-insert">
<bean class="xxxx.AuditLogPostInsertEventListener" />
</entry>
<entry key="post-commit-update">
<bean class="xxxx.AuditLogPostUpdateEventListener" />
</entry>
<entry key="post-commit-delete">
<bean class="xxxx.AuditLogPostDeleteEventListener" />
</entry>
</map>
</property>
</bean>
现在,我尝试在Hibernate 5下创建事件监听器,但不成功
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
...
</list>
</property>
<property name="hibernateProperties">
<props>
...
</props>
</property>
<property name="eventListeners">
<map>
<entry key="post-commit-insert">
<bean class="xxxx.AuditLogPostInsertEventListener" />
</entry>
<entry key="post-commit-update">
<bean class="xxxx.AuditLogPostUpdateEventListener" />
</entry>
<entry key="post-commit-delete">
<bean class="xxxx.AuditLogPostDeleteEventListener" />
</entry>
</map>
</property>
</bean>
显示了以下消息
Bean类[org.springframework.orm.hibernate5.LocalSessionFactoryBean]的无效属性'eventListeners': Bean属性“ eventListeners”不可写或具有无效的setter方法。 setter的参数类型是否与getter的返回类型匹配?
我尝试遵循此stackoverflow,但仍未成功。
PreInsert and PreUpdate Event Listener in hibernate
我更改了如下配置,但仍然没有成功
<bean id="auditInterceptor" class="xxxx.EntityEventListenerRegistry" />
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
...
</list>
</property>
<property name="hibernateProperties">
<props>
...
</props>
</property>
<property name="entityInterceptor" ref="xxxx.EntityEventListenerRegistry" />
</bean>
答案 0 :(得分:1)
根据我的评论,拦截器需要实现 org.hibernate.Interceptor 。
答案 1 :(得分:1)
您也可以像我一样使用java类注册休眠EventListener。
请检查此一项。它可以帮助您。
1)向Integrator注册EventListener。
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor
sessionFactory, SessionFactoryServiceRegistry serviceRegistry)
{
EventListenerRegistry eventListenerRegistry =
serviceRegistry.getService(EventListenerRegistry.class);
/* eventListenerRegistry.getEventListenerGroup(EventType.SAVE)
.appendListener(new SaveUpdateEventListenerImp());*/
eventListenerRegistry.getEventListenerGroup(EventType.SAVE_UPDATE)
.appendListener(new SaveUpdateEventListenerImp());
eventListenerRegistry.getEventListenerGroup(EventType.LOAD)
.appendListener(new LoadEventListenerImp());
eventListenerRegistry.getEventListenerGroup(EventType.REFRESH)
.appendListener(new RefreshEventListenerImp());
}
2)我们可以从这里检查LoadEventListener。只需实现LoadEventListener。 当您从数据库加载Book实体时,LoadEventListener将调用。
public class LoadEventListenerImp implements LoadEventListener {
private static final long serialVersionUID = 1L;
private static Logger logger = LogManager.getLogger(LoadEventListenerImp.class);
@Override
public void onLoad(LoadEvent e, LoadType type) throws HibernateException {
logger.info("onLoad is called.");
Object obj = e.getResult();
if (obj instanceof Book) {
Book book = (Book) obj;
logger.info("Book on load event {} " , book);
}
}
答案 2 :(得分:1)
正如我在this article中所解释的那样,设置Hibernate实体侦听器的最可移植的方法是通过org.hibernate.integrator.spi.Integrator
。这样,您可以使其同时适用于JpaTransactionManager
和HibernateTransactionManager
。
Integrator
界面您需要如下实现Integrator
:
public class ReplicationEventListenerIntegrator
implements Integrator {
public static final ReplicationEventListenerIntegrator INSTANCE =
new ReplicationEventListenerIntegrator();
@Override
public void integrate(
Metadata metadata,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventListenerRegistry =
serviceRegistry.getService(EventListenerRegistry.class);
eventListenerRegistry.appendListeners(
EventType.POST_INSERT,
ReplicationInsertEventListener.INSTANCE
);
eventListenerRegistry.appendListeners(
EventType.POST_UPDATE,
ReplicationUpdateEventListener.INSTANCE
);
eventListenerRegistry.appendListeners(
EventType.PRE_DELETE,
ReplicationDeleteEventListener.INSTANCE
);
}
@Override
public void disintegrate(
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
}
}
通过eventListenerRegistry
,您可以注册事件监听器。
hibernate.integrator_provider
配置属性完成后,您需要设置hibernate.integrator_provider
配置属性。
如果您使用的是 persistence.xml 配置文件,则可以这样设置属性:
<property name="hibernate.integrator_provider"
value="com.vladmihalcea.book.hpjp.hibernate.listener.ReplicationEventListenerIntegrator"
/>
或者,如果您使用Spring Boot,则可以通过 application.properties 来配置此属性,如下所示:
spring.jpa.properties.hibernate.integrator_provider=com.vladmihalcea.book.hpjp.hibernate.listener.ReplicationEventListenerIntegrator
答案 3 :(得分:0)
最后,我尝试了这一点并且工作正常。
@Component
公共类EntityEventListenerRegistry {
@Autowired
private SessionFactory sessionFactory;
@Autowired
private AuditLogPostInsertEventListener auditLogPostInsertEventListener;
@Autowired
private AuditLogPostUpdateEventListener auditLogPostUpdateEventListener;
@Autowired
private AuditLogPostDeleteEventListener auditLogPostDeleteEventListener;
@PostConstruct
public void registerListeners() {
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(auditLogPostInsertEventListener);
registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(auditLogPostUpdateEventListener);
registry.getEventListenerGroup(EventType.POST_COMMIT_DELETE).appendListener(auditLogPostDeleteEventListener);
}
}