Spring + EntityManagerFactory + Hibernate Listeners + Injection

时间:2010-11-10 11:17:43

标签: java hibernate spring jpa hibernate-entitymanager

我有一个简单的问题。可以通过@Ressource或@Autowired向Hibernate Eventlistener添加依赖注入吗?

我将向您展示我的实体管理员配置:

<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

但在这种情况下,我的听众没有弹簧注射。我找到了一个解决方案,但这使用sessionFactory而不是entitymanager oder我可以在我的上下文中修改sessionfactory吗?希望有人有一个好主意或解决方案来处理这个问题!

非常感谢!

1 个答案:

答案 0 :(得分: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,我担心您需要按照概述in this thread使用AOP

或者你可以

  1. 将ApplicationContext存储在ThreadLocal或自定义holder类中,并通过静态方法公开它
  2. 为你的听众提供这样的基类:
  3. 基类:

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

    现在,在你的lifycycle方法中首先调用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" />