Is there a way to define a default transaction manager in Spring
Asked Answered
B

2

17

I have an existing application that uses the Hibernate SessionFactory for one database. We are adding another database for doing analytics. The transactions will never cross so I don't need JTA, but I do want to use JPA EntityManager for the new database.

I've set up the EntityManager and the new transaction manager, which I've qualified, but Spring complains that I need to qualify my existing @Transactional annotations. I'm trying to find a way to tell Spring to use the txManager one as the default. Is there any way of doing this? Otherwise I'll have to add the qualifier to all the existing @Transactional annotations which I would like to avoid if possible.

  @Bean(name = "jpaTx")
  public PlatformTransactionManager transactionManagerJPA() throws NamingException {
    JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());

    return txManager;
  }

  @Bean
  public PlatformTransactionManager txManager() throws Exception {
    HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory());
    txManager.setNestedTransactionAllowed(true);

    return txManager;
  }

Error I'm getting

No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2:

Thanks

Bailee answered 10/4, 2013 at 21:24 Comment(0)
B
34

I was able to solve this using the @Primary annotation

  @Bean(name = "jpaTx")
  public PlatformTransactionManager transactionManagerJPA() throws NamingException {
    JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());

    return txManager;
  }

  @Bean
  @Primary
  public PlatformTransactionManager txManager() throws Exception {
    HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory());
    txManager.setNestedTransactionAllowed(true);

    return txManager;
  }
Bailee answered 11/4, 2013 at 12:54 Comment(2)
Can this be done in the XML as we already have the Transaction Manager defined in XML. Thanks.Stemware
@Mustafa Yes, you just use the attribute 'primary' and set it to 'true' on the bean you wish to be the primary.Bailee
C
0

Since the same type of bean is produced from two methods, you must qualify the @Transactional annotation with the named bean. An easy way around to suite your need will be to use two different Spring application contexts. One operating with the old data source and one operating with new. Each of these contexts will have only one method producing the PlatformTransactionManager instance.

Cooky answered 10/4, 2013 at 23:5 Comment(1)
Pulling the new datasource configuration into a new file (and in a separate jar) does not help. Same error.Bailee

© 2022 - 2024 — McMap. All rights reserved.