Hello,
in the past, yes it’s true, I have already asked whether it is possible to “mix” a Persistence-Layer
primarily based on the Spring classes (@beans) together with Axon, i.e. to use those beans…
- org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,
- org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter,
- org.springframework.orm.jpa.JpaTransactionManager
as base for an Axon application through slight modifications like “joint-”, “hinge-” or “adapter-” class(es) or other idioms.
I don’t mean to create a duplicate. In the other thread I was even more greenhornish and mistook two concepts. Which is why I hope you allow me to pose the question correct here. Thank you very much, if so.
For the question from above take for instance the following persistence-layer Java Config:
(I know it may not be actually functioning, but it’s at least an apt scaffold)
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{
@Autowired
private Environment env;
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/spring_jpa");
dataSource.setUsername( "tutorialuser" );
dataSource.setPassword( "tutorialmy5ql" );
return dataSource;
}
@Bean
private HibernateJpaVendorAdapter vendorAdaptor() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
return vendorAdapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdaptor());
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
entityManagerFactoryBean.setJpaProperties(jpaHibernateProperties());
return entityManagerFactoryBean;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
return transactionManager;
}
// http://www.java2s.com/example/java-api/org/springframework/dao/annotation/persistenceexceptiontranslationpostprocessor/persistenceexceptiontranslationpostprocessor-0-0.html
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
}
}
But the important thing is that the above will at least not work in an Axon application for the following reason alone (which is the thing that is important for this thread):
In Event Bus & Event Store - Axon Reference Guide
there is the quote
So Axon would need at least a @bean
called entityManagerProvider()
that returns the entityManager from the Spring-persistence unit
, that is, from LocalContainerEntityManagerFactoryBean
in the example above (I think this choice is typical, is it not?)
In the old thread it was discussed to solve this by a somewhat hacky construction/idiom, which would first define a class like the following (see the org.axonframework.common.jpa.EntityManagerProvider interface)
public class MyEntityManagerProvider implements ContainerManagedEntityManagerProvider {
private EntityManager entityManager;
@Override
public EntityManager getEntityManager() {
return entityManager;
}
@PersistenceContext(unitName = "myPersistenceUnit")
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
And then create a @bean like so:
@Bean
MyEntityManagerProvider entityManagerProvider() {
em = new MyEntityManagerProvider();
return em.getEntityManager();
}
Now, my question is, whether there is maybe a better solution for this? I could use the ContainerManagedEntityManagerProvider
class for instance as well and provide the @PersistenceContext
via @Qualifier in its setEntityManager()
-method ? Not sure if that works or if I have to create an own implementation of the interface for a custom choice of the persistence-unit. Probably I would have.
Also: Are there other such “joint-”/“hinge-” or “adapter-” classes in order to mix or use a run-off-the-mill Spring Persistence-Layer
together with Axon ? Or will it work with just that one “caveat” ?
Thanks !