Gli ascoltatori Primavera + EntityManagerFactory + Hibernate + Iniezione
-
30-09-2019 - |
Domanda
Ho una semplice domanda. E 'possibile aggiungere l'iniezione di dipendenza attraverso @Ressource o @Autowired al Hibernate EventListener?
ti mostrerò la mia configurazione 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>
Al momento posso registrare la mia ascoltatore via jpa.properties,
hibernate.ejb.event.load=com.example.hibernate.events.LoadEvent
ma in questo caso non ho iniezione primavera nel mio ascoltatore. Ho trovato una soluzione, ma questo uso il sessionFactory e non l'oder EntityManager posso modifiy la SessionFactory nel mio contesto? Speriamo che qualcuno ha una buona idea o solutionhow per affrontare questa problematica!
Un grande grazie!
Soluzione
Se è stato utilizzato SessionFactory, questa sarebbe la configurazione:
<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>
Ma dal momento che si sta utilizzando JPA, ho paura è necessario utilizzare AOP come indicato in questa discussione
In alternativa, è possibile
- memorizzare l'ApplicationContext in un ThreadLocal o di una classe supporto personalizzato ed esporre attraverso un metodo statico
- hanno una classe di base per i vostri ascoltatori qualcosa di simile:
Classe di base:
public abstract class ListenerBase{
protected void wireMe(){
ApplicationContext ctx = ContextHelper.getCurrentApplicationContext();
ctx.getAutowireCapableBeanFactory().autowireBean(this);
}
}
Ora nei tuoi metodi lifycycle chiamare wireMe()
prima.
Aggiornamento:
Ecco un esempio di implementazione 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(){
}
}
Filo nella vostra configurazione di Spring Bean in questo modo:
<bean class="com.mycompany.ContextHelper" factory-method="getInstance" />