Spring + EntityManagerFactory + Hibernate 监听器 + 注入

8

我有一个简单的问题。是否可以通过@Ressource或@Autowired向Hibernate事件监听器添加依赖注入?

我将展示我的实体管理器工厂配置:

<bean id="entityManagerFactory" class="org.hibernate.ejb.EntityManagerFactoryImpl">
    <qualifier value="entityManagerFactory" />
    <constructor-arg>
        <bean
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitManager">
                <bean
                    class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManagerr">
                    <property name="defaultDataSource" ref="dataSource" />
                </bean>
            </property>
            <property name="dataSource" ref="dataSource" />
            <property name="persistenceUnitName" value="mis" />
            <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
            <property name="jpaProperties" ref="jpa.properties" />
            <property name="jpaDialect" ref="jpaDialect" />
            <property name="jpaVendorAdapter">
                <bean
                    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="generateDdl" value="true" />
                    <property name="database">
                        <util:constant
                            static-field="org.springframework.orm.jpa.vendor.Database.POSTGRESQL" />
                    </property>
                    <property name="showSql" value="true" />
                </bean>
            </property>

        </bean>
    </constructor-arg>
</bean>

目前,我通过jpa.properties注册我的监听器。

hibernate.ejb.event.load=com.example.hibernate.events.LoadEvent

但在这种情况下,我的监听器中没有Spring注入。我找到了一个解决方案,但是它使用sessionFactory而不是entityManager, 我能否在我的上下文中修改sessionFactory?希望有人有一个好的想法或解决方案来处理这个问题!

非常感谢!

1个回答

16
如果你使用SessionFactory,那么配置如下所示:

<bean id="mySessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <!-- Stripped other stuff -->
    <property name="eventListeners">
        <map>
            <entry key="pre-load">
                <bean class="com.mycompany.MyCustomHibernateEventListener1" />
            </entry>
            <entry key="pre-persist">
                <bean class="com.mycompany.MyCustomHibernateEventListener2" />
            </entry>
        </map>
    </property>
</bean>

但是由于您正在使用JPA,我担心您需要按照此线程中所述使用AOP。

或者您可以:

  1. 将ApplicationContext存储在ThreadLocal或自定义持有类中,并通过静态方法公开它
  2. 为您的侦听器创建一个基类,类似于以下内容:

基类:

public abstract class ListenerBase{

    protected void wireMe(){
        ApplicationContext ctx = ContextHelper.getCurrentApplicationContext();
        ctx.getAutowireCapableBeanFactory().autowireBean(this);
    }

}

现在在你的生命周期方法中,首先调用wireMe()


更新:

这是ContextHelper的一个示例实现:

public final class ContextHelper implements ApplicationContextAware{

    private static final ContextHelper INSTANCE = new ContextHelper();
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext){
        this.applicationContext = applicationContext;
    }

    public static ApplicationContext getCurrentApplicationContext(){
        return INSTANCE.applicationContext;
    };

    public static ContextHelper getInstance(){
        return INSTANCE;
    }

    private ContextHelper(){
    }

}

像这样在您的Spring Bean配置中进行连接:

<bean class="com.mycompany.ContextHelper" factory-method="getInstance" />

你好,感谢你的回复。请问你能告诉我在哪里找到ContextHelper吗?我已经在Hibernate.search.util和Hibernate.search.event中找过了,但是这些类中都没有"getCurrentApplicationContext()"方法。 - moohkooh
这是一个你需要创建的类。我现在附上了一个示例版本。 - Sean Patrick Floyd
非常感谢,它起作用了。我无法告诉你,你帮了我多少忙!非常感谢!! - moohkooh
1
我只是想指出这篇优秀的文章:http://baard.rehn.no/node/51略有不同的方法,但最终效果相同。我喜欢它,因为它将IOC容器的选择与EntityListener分开。我使用了一个实现InitializingBean和DependencyInjector的单个类。理论上,我应该能够从Spring切换到其他容器,而持久层是无感知的。我确实在我的@Entity类上声明了监听器。通过Spring的applicationContext.xml设置默认监听器 - 我不希望这些类意识到自己正在被监听。 - Doug Moscrop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接