Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HibernateJpaAutoConfiguration should be applied before DataSourceTransactionManagerAutoConfiguration #38861

Closed
tvahrst opened this issue Dec 19, 2023 · 3 comments
Labels
type: bug A general bug
Milestone

Comments

@tvahrst
Copy link

tvahrst commented Dec 19, 2023

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)
@tvahrst tvahrst changed the title HibernateJpaAutoConfiguration should have precedence over DataSourceTransactionManagerAutoConfiguration HibernateJpaAutoConfiguration should be applied before DataSourceTransactionManagerAutoConfiguration Dec 19, 2023
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 19, 2023
@philwebb philwebb added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 20, 2023
@philwebb philwebb added this to the 3.1.7 milestone Dec 20, 2023
@philwebb
Copy link
Member

Thanks for the report @tvahrst, I've added the additional condition.

@vanta
Copy link

vanta commented Dec 21, 2023

@philwebb when it will be ported to v3.2? I mean when do you plan to release it?

@bclozel
Copy link
Member

bclozel commented Dec 21, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants