【问题标题】:How do I set up an event listener on a Hibernate 4 entity?如何在 Hibernate 4 实体上设置事件侦听器?
【发布时间】:2012-05-23 01:25:52
【问题描述】:

我正在使用 Spring 3.1.0.RELEASE 和 Hibernate 4.0.1.Final。我想在从数据库加载实体 bean 时调用它的事件侦听器,但我不知道应该使用什么事件。我像这样在我的 DAO 中加载我的实体

@Repository("eventFeedsDao")
public class EventFeedsDaoImpl implements EventFeedsDao {

    ...
    @Autowired
    private SessionFactory sessionFactory;

    ...

    @Override
    public EventFeed findById(final Integer id) { 
        EventFeed eventFeed = null;
        final Session session = sessionFactory.getCurrentSession();
        final Criteria crit = session.createCriteria(EventFeed.class).add(Restrictions.eq("id", id));
        final List<EventFeed> results = crit.list();
        if (results != null && results.size() > 0) { 
            eventFeed = results.get(0);
        }   // if
        return eventFeed;       
    }   // findById 

这是我尝试设置事件连接的方式...

@Component
public class HibernateEventWiring {

    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    private EventMavenLoadListener listener;

    @PostConstruct
    public void registerListeners() {
        EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory)
            .getServiceRegistry().getService(EventListenerRegistry.class);
        registry.getEventListenerGroup(EventType.LOAD).appendListener(listener);
    }
}

而我的监听类如下...

@Component
public class EventMavenLoadListener implements LoadEventListener {

    ...

    @Override
    public void onLoad(final LoadEvent event, final LoadType loadType) throws HibernateException {
        if(EventFeed.class.getName().equals(event.getEntityClassName())){
            EventFeed entity = (EventFeed) event.getInstanceToLoad();
            entity.setNetUtilsService(netUtilsService);
        }   // if
    }

}

但永远不会调用“onLoad”事件。我究竟做错了什么?我应该使用另一个事件吗?

【问题讨论】:

    标签: java spring hibernate listener


    【解决方案1】:

    由于某些我仍然无法理解的原因,EventType.PRE_LOAD 事件类型是要走的路。这行得通。

    @Component
    public class HibernateEventWiring {
    
        @Autowired
        private SessionFactory sessionFactory;
    
        @Autowired
        private EventMavenLoadListener listener;
    
        @PostConstruct
        public void registerListeners() {
            final EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory)
                    .getServiceRegistry().getService(EventListenerRegistry.class);
            registry.getEventListenerGroup(EventType.PRE_LOAD)
                    .appendListener((PreLoadEventListener) listener);
        }
    }
    

    【讨论】:

      【解决方案2】:

      加载事件仅在单独加载实体时触发(session.get、初始化代理、获取渴望一对一的关联)。

      然而,加载前和加载后事件遵循 JPA 定义的行为,并在加载实体数据之前和之后发生,无论“数据加载”如何发生。

      这是一个坏名冲突的案例。

      顺便说一句,Hibernate 4 中指定事件侦听器的首选方法是使用 org.hibernate.integrator.spi.Integrator。见http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html_single/#integrators

      【讨论】:

      • 关于集成器,为什么这比我发现的事件布线类更好?我假设我必须用“@Component”注释集成器类?感谢您的建议,-
      • 可以通过 JDK ServiceLoader 类/模式发现集成器。这使得它在您不控制 SessionFactory 构建(Spring、JPA 等)的情况下更容易使用。你的意思是@Component 用于发现目的吗?如果是这样,不,它的发现是通过我提到的 ServiceLoader。它包含在我上面链接的文档中,尽管您必须转到链接部分docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html_single/…
      猜你喜欢
      • 2012-05-22
      • 1970-01-01
      • 2011-10-14
      • 2017-07-07
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      相关资源
      最近更新 更多