【问题标题】:Spring + EntityManagerFactory +Hibernate Listeners + InjectionSpring + EntityManagerFactory +Hibernate 监听器 + 注入
【发布时间】:2011-05-07 19:56:41
【问题描述】:

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

我将向你展示我的 entitymanagerfactory 配置:

<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 或者我可以在我的上下文中修改 sessionfactory 吗?希望有人有一个好主意或解决方案如何处理这个问题!

非常感谢!

【问题讨论】:

    标签: java hibernate spring jpa hibernate-entitymanager


    【解决方案1】:

    如果你使用了 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 或自定义持有者类中,并通过静态方法公开它
    2. 为您的听众创建一个基类,如下所示:

    基类:

    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" />
    

    【讨论】:

    • 您好,感谢您的回复。你能告诉我在哪里可以找到 ContextHelper 吗?我有一个来自 Hibernate.search.util。和 Hibernate.search.event 并且没有方法“getCurrentApplicationContext()”
    • 这是一个你需要创建的类。我现在附上了一个示例版本。
    • 非常感谢,它有效。我不能告诉你,你帮助了我多少!!非常感谢!
    • 我只是想指出这篇优秀的文章:baard.rehn.no/node/51 方法略有不同,最终结果相同。我喜欢它,因为它使 IOC 容器选择与 EntityListener 分开。我使用了一个实现 InitializingBean 和 DependencyInjector 的类。从理论上讲,我应该能够从 Spring 切换到其他容器,并且 Persistence 层不知道。我确实在我的@Entity 类上声明了监听器。我通过 Spring applicationContext.xml 设置默认侦听器 - 我不希望类知道它们正在被侦听。
    猜你喜欢
    • 2018-07-01
    • 2019-09-07
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 2022-10-24
    • 2014-03-30
    相关资源
    最近更新 更多