Spring + EntityManagerFactory + Hibernate Listeners + Injection [英] Spring + EntityManagerFactory +Hibernate Listeners + Injection

查看:116
本文介绍了Spring + EntityManagerFactory + Hibernate Listeners + Injection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我会告诉你我的entitymanagerfactory配置:

 < bean id =entityManagerFactoryclass =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 =defaultDataSourceref =dataSource/>
< / bean>
< / property>
< property name =dataSourceref =dataSource/>
< property name =persistenceUnitNamevalue =mis/>
< property name =persistenceProviderClassvalue =org.hibernate.ejb.HibernatePersistence/>
< property name =jpaPropertiesref =jpa.properties/>
< property name =jpaDialectref =jpaDialect/>
< property name =jpaVendorAdapter>
< bean
class =org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter>
< property name =generateDdlvalue =true/>
< property name =database>
< util:constant
static-field =org.springframework.orm.jpa.vendor.Database.POSTGRESQL/>
< / property>
< property name =showSqlvalue =true/>
< / bean>
< / property>

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

目前,我通过jpa.properties注册了侦听器,

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

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



非常感谢!

解决方案

如果您使用了SessionFactory,那么这将是配置:

class =org.springframework.orm.hibernate3.LocalSessionFactoryBean>
<! - 剥离其他内容 - >
< 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,恐怕您需要按照在此主题



或者您可以


  1. 将ApplicationContext存储在ThreadLocal或自定义持有者类中,并通过静态方法公开它

  2. 有一个基础类为您的听众这样的事情:

基类:



<$ p $公共抽象类ListenerBase {

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







现在在你的lifycycle方法中调用 wireMe() first。






更新:



以下是 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.ContextHelperfactory-method =getInstance/> 


i have a simple question. Its possible to add dependency injection via @Ressource or @Autowired to the Hibernate Eventlistener?

I will show you my entitymanagerfactory configuration:

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

At the moment i register my listener via jpa.properties,

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

but in this case i have no spring injection in my listener. I found a solution, but this use the sessionFactory and not the entitymanager oder can i modifiy the sessionfactory in my context? Hopefully someone have a nice idea or solutionhow to deal with this problematic!

Big thanks!

解决方案

If you used SessionFactory, this would be the configuration:

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

But since you are using JPA, I'm afraid you need to use AOP as outlined in this thread

Or you can

  1. store the ApplicationContext in a ThreadLocal or a custom holder class and expose it through a static method
  2. have a base class for your listeners something like this:

Base class:

public abstract class ListenerBase{

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

}

Now in your lifycycle methods call wireMe() first.


Update:

Here is a sample implementation of 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(){
    }

}

Wire it in your Spring Bean configuration like this:

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

这篇关于Spring + EntityManagerFactory + Hibernate Listeners + Injection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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