Spring Boot和Spring Data JPA的Hibernate拦截器或侦听器 [英] Hibernate interceptor or listener with Spring Boot and Spring Data JPA

查看:117
本文介绍了Spring Boot和Spring Data JPA的Hibernate拦截器或侦听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在保存一个对象的子集合之前执行一些检查(cascade = all)。

我使用Spring Boot和Spring Data JPA并想知道哪种方法最好:Hibernate侦听器或拦截器。每个的优点/缺点是什么?



在使用XML配置XML之前,我已经使用了Hibernate侦听器,如下所示:

 < property name =eventListeners> 
< map>
< entry key =post-update>
< list>
< ref bean =myListener/>
< / list>
< / entry>
< / map>
< / property>

关于会话工厂(较老的项目)。但现在我的大部分配置都在注释中(导致Spring Boot),并且我希望配置尽可能简单和轻便,所以也许拦截器会是更好的解决方案。



谢谢。

解决方案

我为自己做了很多周到的工作,并认为我会分享我(我在底部包含了有用的(非内联)链接)。



拦截器



使用拦截器,可以扩展 org.hibernate.EmptyInterceptor 类并覆盖你想截取的方法。
您可能需要 onSave(... ) 在你的情况。

  package foo.bar; 

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;
$ b public class MyInterceptor extends EmptyInterceptor {
@Override
public boolean onSave(Object entity,Serializable id,Object [] state,String [] propertyNames,Type [] types){
//在这里做你的支票
return false;


您必须用Spring / Hibernate注册你的拦截器
您可以在 application.properties或application.yml

  spring:
jpa:
属性:
hibernate.ejb.interceptor:foo.bar.MyInterceptor



拦截器的好处在于它(可能)更少的代码和相对简单的配置。
缺点是您的整个应用程序只能有一个API,而且API可能会让您感到困惑。

事件监听器



对于事件,您实现了Hibernate的一个 org.hibernate.event.spi。* Listener 接口。
您可能需要 org.hibernate.event.spi.PreInsertEventListener 在您的案例中。



您必须注册您的活动在 EventListenerRegistry 中。
要做到这一点,你可以让你的课程 @Component @Autowire EntityManagerFactory 添加到你的类中,然后创建一个 @PostConstruct 方法来注册你的类。

  package foo.bar; 

import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreInsertEvent;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;

@Component
public class MyEventListener实现PreInsertEventListener {
@Autowired
private EntityManagerFactory entityManagerFactory;

@PostConstruct
private void init(){
SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry()。getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(this);
}

@Override
public boolean onPreInsert(PreInsertEvent preInsertEvent){
//在这里做你的支票
return false;


听众的好处是你可以拥有多少如你所愿,API比拦截器更好,代码和配置都在同一个地方。
缺点是配置的时间越来越长,越来越多。







I'd like to run some checks prior to saving a collection of children of an object (cascade = all).

I am using Spring Boot and Spring Data JPA and was wondering what approach would be the best: a Hibernate listener or an interceptor. What are the pros/cons of each ? Do you happen to have an example for the one you consider the best approach ?

I have used Hibernate listeners before configured in XML like this:

    <property name="eventListeners">
        <map>
            <entry key="post-update">
                <list>
                    <ref bean="myListener" />
                </list>
            </entry>
        </map>
    </property>

on the session factory (older project). But now most of my configs are in annotations (cause Spring Boot) and I want to keep the configs as simple and light as possible, so maybe an interceptor would be a better solution.

Thank you.

解决方案

I did a lot of looking around on this for myself and thought I'd share what I got working (I included the helpful (non-inline) links at the bottom).

Interceptor

To use an interceptor, you extend the org.hibernate.EmptyInterceptor class and override the methods you want to intercept. You probably want onSave(...) in your case.

package foo.bar;

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;

public class MyInterceptor extends EmptyInterceptor {
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        // do your checks here
        return false;
    }
}

You have to register your interceptor with Spring/Hibernate. You can do this in your application.properties or application.yml.

spring:
  jpa:
    properties:
      hibernate.ejb.interceptor: foo.bar.MyInterceptor

The upsides to an interceptor are that it is (potentially) less code and relatively simple configuration. The downsides are that you can only have one for your entire application and the API can be confusing to work with.

Event Listener

For events, you implement one of Hibernate's org.hibernate.event.spi.*Listener interfaces. You probably want the org.hibernate.event.spi.PreInsertEventListener in your case.

You have to register your event in the EventListenerRegistry. To do this, you can make your class a @Component, @Autowire the EntityManagerFactory into your class, and create a @PostConstruct method to register your class.

package foo.bar;

import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreInsertEvent;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;

@Component
public class MyEventListener implements PreInsertEventListener {
    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @PostConstruct
    private void init() {
        SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
        EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
        registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(this);
    }

    @Override
    public boolean onPreInsert(PreInsertEvent preInsertEvent) {
        // do your checks here
        return false;
    }
}

The upsides to listeners are that you can have as many as you want, the API is nicer than the interceptor's, and the code and the configuration are all in one place. The downside is that the configuration is longer and more involved.


这篇关于Spring Boot和Spring Data JPA的Hibernate拦截器或侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆