J'ai configuré deux unités persistantes avec les gestionnaires d'entités configurés comme indiqué ci-dessous:
<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>
J'ai ensuite configuré les gestionnaires de transactions comme
<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"/>
Au départ, je n'en avais qu'un configuré et il s'appelait "transactionManager". Ajouter une unité persistante supplémentaire semble générer une erreur. Une chose que je ne comprends pas, si j'ai configuré deux unités persistantes (chacune pour une base de données distincte), dois-je également configurer un gestionnaire d'entité individuel et un gestionnaire de transactions pour chaque source de données?
L'erreur que j'obtiens est montrée ci-dessous: (J'ai recherché tout le dossier et je ne peux pas trouver n'importe où où il y a une référence pour "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)
J'utilise Spring avec Jpa/Hibernate.
Merci
La valeur par défaut de l'attribut transaction-manager est transaction-manager. Dans votre cas, vous devez spécifier le gestionnaire de transactions que vous souhaitez utiliser par méthode ou service comme ceci:
@Service
@Transactional(value="LiveTransactionManager")
class someClass...
ou
@Transactional(value="ArchiveTransactionManager")
public void someMethod
En fait, il y a is une façon d'utiliser TransactionManager nommé avec Spring Data JPA. Cela fonctionne pour moi:
<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>
J'utilise Java et en spécifiant transactionManagerRef était la solution pour moi:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "myCustomEntityManagerFactory",
basePackages = {"ua.demitt.other.path.to.repos"},
transactionManagerRef = "myCustomTransactionManager" )
Dans votre fichier @Configuration, s'il s'agit de votre source de données:
@Bean(name = "dataSource")
public DataSource getDataSource() {
return DataSourceBuilder
.create()
.username(username)
.password(password)
.url(url)
.build();
}
ce serait votre bean de gestionnaire de transactions:
@Bean(name = "DataSourceTransactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
Annotez ensuite la méthode de service que vous souhaitez être transactionnelle:
@Transactional(transactionManager = "DataSourceTransactionManager", timeout = 60, rollbackFor = { Exception.class})