No bean named 'transactionManager' is defined
Asked Answered
T

4

27

I have configured two persistent units with the entity managers set up as show below:

<bean id="liveEntityManagerFactory" 
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          p:dataSource-ref="LiveDataSource">          

          <property name="persistenceUnitName" value="LivePersistenceUnit" />
    </bean>

    <bean id="archiveEntityManagerFactory" 
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          p:dataSource-ref="ArchiveDataSource">          

          <property name="persistenceUnitName" value="ArchivePersistenceUnit" />
    </bean>

I then configured the transaction managers as

 <bean id="LiveTransactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="liveEntityManagerFactory"/>

    <bean id="ArchiveTransactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="archiveEntityManagerFactory"/>  

I originally had just one configured and it was called "transactionManager". Addint an additional persistent unit seems to generate an error. One thing i dont understand, if i configured two persistent units (each for a separate database) do i also need to configure an individual entity manager and a transaction manager for each datasource?

The error that i get is shown below: (I have search all file and i cant find anywhere where there is a reference for "transactionManager")

org.springframework.ws.soap.client.SoapFaultClientException: No bean named 'transactionManager' is defined
    at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:37)
    at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:774)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:600)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:384)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:370)
    at com.ws.client.SoapTest.testFail(SoapTest.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
    at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)

I am using Spring with Jpa/Hibernate.

Thanks

Tooth answered 23/5, 2012 at 12:12 Comment(3)
You should use only one TransactionManager, and its bean should be named "transactionManager".Retardant
The transaction manager has to have a reference to the EntityManagerFactoryBean as shown above. How would i configure it if i have two EntityManagerFactoryBean? (Each for a separate datasource)Tooth
JPATransactionManager works if you are using only one EntityManager. If using more than one, you need consistency between all your datasources, so you need to resort to org.springframework.transaction.jta.JtaTransactionManager. Are you familiar with JTA?Retardant
S
27

The default value for the transaction-manager attribute is transaction-manager. In your case, you should specify which transaction manager you want to use per method or service like this:

@Service
@Transactional(value="LiveTransactionManager") 
class someClass...

or

@Transactional(value="ArchiveTransactionManager") 
public void someMethod
Safety answered 23/5, 2012 at 12:46 Comment(2)
This will not work on the service class itself. It must be per method, or else you will get the same exception. However, per the documentation: The default <tx:annotation-driven> target bean name transactionManager will still be used if no specifically qualified PlatformTransactionManager bean is found.Platto
Where should I define transactionManager in spring boot?Culicid
E
8

Actually, there is a way to use named TransactionManager with Spring Data JPA. This works for me:

<bean id="myTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEntityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="myTransactionManager"/>

<jpa:repositories base-package="com.xxx.yyy" entity-manager-factory-ref="myEntityManagerFactory" transaction-manager-ref="myTransactionManager">
</jpa:repositories>
Edmondedmonda answered 25/1, 2014 at 8:42 Comment(0)
T
2

I use java configuration and specifying the transactionManagerRef was solution for me:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "myCustomEntityManagerFactory",
    basePackages = {"ua.demitt.other.path.to.repos"},
    transactionManagerRef = "myCustomTransactionManager" )
Towage answered 23/4, 2019 at 20:4 Comment(0)
A
0

In your @Configuration file, if this is your dataSource:

@Bean(name = "dataSource")
public DataSource getDataSource() {
    return DataSourceBuilder
            .create()
            .username(username)
            .password(password)
            .url(url)
            .build();
}

this would be your transaction manager bean:

@Bean(name = "DataSourceTransactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager() {
    return new DataSourceTransactionManager(getDataSource());
}

Then annotate the service method you would like to be transactional:

@Transactional(transactionManager = "DataSourceTransactionManager", timeout = 60, rollbackFor = { Exception.class})
Adah answered 8/1, 2020 at 22:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.