Spring + EntityManagerFactory + Hibernate Слушатели + Инъекция - PullRequest
8 голосов
/ 10 ноября 2010

У меня простой вопрос.Можно ли добавить внедрение зависимостей через @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. Могу ли я изменить сеансовый завод в моем контексте?Надеюсь, у кого-то есть хорошая идея или решение, как справиться с этой проблемой!

Большое спасибо!

1 Ответ

16 голосов
/ 10 ноября 2010

Если вы использовали 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);
    }

}

Теперь в вашем методе 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" />
...