ChrisDekker
ChrisDekker

Reputation: 1763

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.

Upvotes: 2

Views: 2582

Answers (2)

antoniOS
antoniOS

Reputation: 419

To setup the default transation manager which will be used you can annotate your transaction manager creation bean with @Primaty, like:

  @Primary
  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    return new JpaTransactionManager(entityManagerFactory);
  }

Upvotes: 0

M. Deinum
M. Deinum

Reputation: 124516

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.

Upvotes: 2

Related Questions