Implementing an Entity- /Transaction-manager compatible with JGroups?

Hello,

first: What is this error message: “Title seems unclear, one or more words is very long?” What does it want to tell me?

Original title should be: “Implementing an Entity- /Transaction-manager compatible with JGroups (LocalContainerEntityManagerFactoryBean)”

I have the following beans as part of a Spring persistence context configuration:

@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;
   }

How would I implement this in Axon ? Do I have to substitute all classes in here for Axon classes and just keep the dataSource bean ?

I am not using AxonServer and instead for distribution of the command processing I want to use the JGroup extension.

So first there are the classes and code-snippets named in the following link whereas, because I exclude AxonServer from the classpath, I have to implement an EmbeddedEventStore, dependent on a JpaEventStorageEngine, dependent on a JPA persistence-unit.

See docs.axoniq.io > Event Bus & Event Store > Embedded Event Store

It needs an EntityManagerProvider. So I could proceed to subclass like this:

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

Then I would create a bean

@Bean
MyEntityManagerProvider entityManagerProvider() { ... }

BUT

The entry axon docs > Extensions > JGroups > Configuration in Spring (Boot) suggests to use org.axonframework.commandhandling.distributed.jgroups.JGroupsConnectorFactoryBean
But… for what? En lieu of LocalContainerEntityManagerFactoryBean ? The name sounds similar and it speaks about the ApplicationContext so it should have something to do with the EntityManager.

Can you please tell me if I should use this connector factory and how I intertwine it with the entitymanager ?

Do I have to change the Spring LocalEntityManagerFactoryBean for an Axon class that produces an own Axon EntityManager in order to use it ?

Thanks!

Yours sincerly
überSpotz

Hi überSpotz,

the JGroupsConnectorFactoryBean has nothing to do with JPA, the EntityManager, or its FactoryBean. The JGroups connector for the DistributedCommandBus needs to be available in the application context, and that’s what the JGroupsConnectorFactoryBean does. So just define it as an additional bean, not instead of anything else.

Hope this helps.

Dear Allard,

Yes it does, thank you very much.

May I ask you (or any other kind person willing to answer) to answer one other important question or two of an enthusiastic greenhorn:

  1. Can I use the Spring JPA Configuration with the classes above, with a HikariDataSource (I think this is the default if Hikari is on the classpath in Spring at last) together with Axon (toss in Hibernate as Jpa Provider) ?

  2. Also: Is my approach to MyEntityManagerProvider correct to 1) derive and define the class in a first step and 2) in a second step define a Bean that returns an instance of it?

  3. How compatible is Axon with your run-off-the-mill persistence layer configuration such as described here for example?

    Also in the case that it is theoretically compatible, are does Axon come with its own classes that I should or may use in order to build a Jpa persistence-tier configuration also involving a TransactionManager and EntityManagement instead of Spring’s? Is that possible with Axon classes alone? What is “lege artis” for Axon configuration?

    It could be to, In general, use Axon “wrapping” classes where possible at last like org.axonframework.spring.messaging.unitofwork.SpringTransactionManager that at least only uses the Spring classes “under the hood” in order to be more compatible? Or is the whole JPA configuration from Spring just as good in Axon as when writing a pure SpringBoot application?

I guess I will leave it at that and make a new thread for my question on how to use the JGroupsConnectorFactoryBean and the Distributed- prefixed classes then.

Thanks for your patience.

Yours sincerely
drSpotzenstein

Well, it tells you that a word in the title is too long :wink:
In your case, it’s most likely the “LocalContainerEntityManagerFactoryBean” word.
The default limit for the length of a word in a title is 30 characters. I just increased it to 50.

Hi,
sorry for the late reply, this message escaped my attention.

Typically, you would simply use a single EntityManager and TransactionManager inside your application. Axon will re-use these for its specific JPA-based interactions. If you keep the Spring Boot auto-configured defaults, Axon’s entity classes will also be automatically detected. If you specifically configure your entities, then you’d also need to specify the ones used by Axon. Which ones these are, depends on which JPA-based components from Axon you use.

If you only have a single EntityManager in your application, then you don’t need to specify an EntityManagerProvider. The Axon SpringBoot Autoconfiguration will configure one for you. If you have multiple persistence contexts and want Axon to use a specific one, then your approach with the MyEntityManagerProvider is indeed correct.

Hope this helps.