Skip to content

HibernateJpaAutoConfiguration should be applied before DataSourceTransactionManagerAutoConfiguration #38861

@tvahrst

Description

@tvahrst

HibernateJpaAutoConfiguration should be applied before DatasourceTransactionManagerAutoconfiguration

Explanation:
HibernateJpaAutoConfiguration imports HibernateJpaBaseConfiguration which contains a Bean definition of a JPATransactionManager with ConditionalOnMissingBean(TransactionManager) (in superclass JpaBaseConfiguration):

@Bean
@ConditionalOnMissingBean(TransactionManager.class)
public PlatformTransactionManager transactionManager(
		ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
	JpaTransactionManager transactionManager = new JpaTransactionManager();
	transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
	return transactionManager;
}

The DatasourceTransactionManagerAutoConfiguration does also define a TransactionManager Bean with the same condition:

@Bean
@ConditionalOnMissingBean(TransactionManager.class)
DataSourceTransactionManager transactionManager(Environment environment, DataSource dataSource,
		ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
	DataSourceTransactionManager transactionManager = createTransactionManager(environment, dataSource);
	transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
	return transactionManager;
}

If the application uses Hibernate, the Hibernate auto-configuration should match, which means that the HibernateJpaAutoConfiguration should be applied before DatasourceTransactionManagerAutoConfiguration.

Currently, there is no explicit before/after Condition for these Autoconfigurations, but the 'natural' sort order leads 'by chance' to the right order.

We provided for our application a additional auto-configuration with these conditions:

@AutoConfiguration(
	after = {RestTemplateAutoconfiguration.class, TransactionAutoConfiguration.class}
)

which leaded to a different order of many Spring auto-configuration, especially now sorting DatasourceTransactionManagerAutoConfiguration before HibernateJpaAutoConfiguration. As a result, we saw this exception during execution of the application:

14:22:47 [43-exec-7] ERROR d.l.a.a.b.r.GlobalExceptionHandler  - Caught unhandled exception
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:400)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:234)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:550)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:243)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:164)
...
Caused by: jakarta.persistence.TransactionRequiredException: no transaction is in progress
	at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:483)
	at org.hibernate.internal.SessionImpl.checkTransactionNeededForUpdateOperation(SessionImpl.java:2528)
	at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1406)
	at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1401)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions