Skip to content
Advertisement

Set default Transaction Manager in @Transactional annotations?

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.

Advertisement

Answer

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.

Advertisement