Issue
I have a Spring Boot 2.x application with JPA/Hibernate and 2 separate Transaction Managers: 1 per-tenant and 1 application-wide. All entities, repositories and services are separated in different packages.
Whenever I use @Transactional
in my services, I need to explicitly qualify the txManager as either @Transactional(value = "tenantTransactionManager")
or @Transactional(value = "applicationTransactionManager")
.
This is very verbose and error prone since they are just literal strings.
Is there a way I can set the Transaction Manager on the package level, so I don't have to explicitly set this on every usage?
Based on the answer given in Multiple transaction managers with @Transactional annotation, I created a @TenantTransactional
and @ApplicationTransactional
meta-annotation, but this does not let me set the readOnly
flag, which is necessary per-method.
Solution
Given the answer and the fact you have already @TenantTransactional
and @ApplicationTransactional
you can simply use an alias for readOnly
. Adding an alias can be done using @AliasFor
.
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("tenantTransactionManager")
public @interface TenantTransactional {
@AliasFor(attribute="readOnly", annotation=Transactional.class)
boolean readOnly() default false;
}
Ofcourse you can do this for other properties of the @Transactional
annotation as well.
Answered By - M. Deinum