Ne peut pas ouvrir l'EntityManager pour la transaction; nested exception java.lang.IllegalStateException
Je suis tout à fait nouveau pour le Printemps et le Printemps-Lot en particulier.
Encore j'ai réussi à installer le Spring Batch-Admin. J'ai ajouté des travaux personnalisés et Hibernate/JPA, pour la persistance.
Tout fonctionne comme prévu, jusqu'au point où le premier morceau doit être conservé. Puis je recevoir le message d'erreur:
org.springframework.transaction.CannotCreateTransactionException:
Could not open JPA EntityManager for transaction;
nested exception is java.lang.IllegalStateException: Already value
[org.springframework.jdbc.datasource.ConnectionHolder@60d31437]
for key [org.springframework.jdbc.datasource.DriverManagerDataSource@12da4b19]
bound to thread [jobLauncherTaskExecutor-1]
C'est le plein stacktrace:
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@43f9e588] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@84f171a] bound to thread [jobLauncherTaskExecutor-1]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:427)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy41.saveIfUnique(Unknown Source)
at com.qompa.batch.ArticleItemWriter.write(ArticleItemWriter.java:28)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:171)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:150)
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$3.doWithRetry(FaultTolerantChunkProcessor.java:313)
at org.springframework.batch.retry.support.RetryTemplate.doExecute(RetryTemplate.java:240)
at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:187)
at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:213)
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.write(FaultTolerantChunkProcessor.java:402)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:194)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:74)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:386)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@43f9e588] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@84f171a] bound to thread [jobLauncherTaskExecutor-1]
at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:189)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:402)
... 36 more
Le même Travail s'exécute bien dans une application autonome. Le problème se produit uniquement dans le Ressort-Lot-Admin de l'environnement. Ci-dessous vous pouvez voir la la structure du projet et des dépendances:
C'est le app-context.xml qui remplace/s'étend le Lot-Admin configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<context:component-scan base-package="com.company.batch" />
<context:property-placeholder location="classpath:batch.properties" />
<import resource="classpath:/META-INF/spring/batch/jobs/article-job.xml" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.qompa.batch" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="POSTGRESQL"></property>
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="com.company.utils.persistence.CustomPGDialect" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto"></prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<!-- schedule tasks -->
<task:scheduled-tasks>
<task:scheduled ref="articleRetrieval" method="run"
cron="0 0 */4 * * *" />
<task:scheduled ref="articleConversion" method="run"
cron="0 15 */4 * * *" />
</task:scheduled-tasks>
</beans>
Ce que je comprends est que cela a à faire avec la ThreadPoolTaskExecutor à laquelle le jobLauncherTaskExecutor
bean se réfère. Il semble gérer groupement de connexions pour l'exécution simultanée d'emplois ... mais pour être honnête, je n'ai aucune idée de comment faire pour modifier mes configurations à faire ces choses fonctionnent.
[Edit]: je ne suis même pas sûr que c'est le afromentioned ThreadPoolTaskExecutor. Mais il semble s être une mise en œuvre de la TaskExecutor interface.
Si quelqu'un a couru dans un problème similaire, ou a une suggestion comment configurer mon application d'une manière que les transactions peuvent être créés pour mes méthodes de persistance: Merci de me donner un indice!
Pouvez-vous poster plus de résultats si vous les avez?
OriginalL'auteur achingfingers | 2014-01-03
Vous devez vous connecter pour publier un commentaire.
L'erreur vient de JpaTransactionManager ligne 403:
L'erreur signifie que le gestionnaire de transactions est en essayant de lier le source de données (pas le gestionnaire de l'entité) pour le fil, mais la source de données est déjà là et c'est inattendu.
Noter que le gestionnaire de transactions n'avait pas encore commencé à lier l'Entité Gestionnaire de au fil, ce qui allait se passer ensuite à JpaTransactionManager ligne 416:
Il y a deux explications possibles:
Quelqu'un (un autre gestionnaire de transactions?) est l'ajout de la source de données dans le filet avant que le gestionnaire de transactions et de ce qui est inattendu.
Ou personne n'est l'ajout de la source de données dans le gestionnaire de transactions, c'est juste que à la fin de l'exécution de la tâche que personne ne nettoie le fil avant de le retourner à la piscine, peut-être en raison d'une erreur ou d'une exception non gérée.
Une question, est-ce aussi arriver que pour un seul thread d'exécution, ou seulement quand il y a plusieurs?
De trouver quel est le problème, ce sont quelques étapes:
fonctionner avec un minimum nombre de threads qui cause le problème
mettre un point d'arrêt dans
TransactionSynchronizationManager.bindResource()
pour voir qui ajoute le lien vers le fil de discussion. Le point d'arrêt peut être un point d'arrêt conditionnel avec une condition sur le nom du thread: "jobLauncherTaskExecutor-1".equals(Thread.currentThread().getName())mettent également un point d'arrêt dans
TransactionSynchronizationManager.unbindResource()
, pour voir si la source de données est indépendant du thread. lorsque les points d'arrêt frappé, faites défiler la stacktrace et de voir les classes sont la cause de cette.Avez-vous eu la chance d'en voir davantage?
point d'arrêt conditionnel lien cassé
Alors, comment vous résoudre ce problème? ou qu'avez-vous changé dans votre code? s'il vous plaît!
OriginalL'auteur Angular University
Ce qui se passe normalement, lorsque vous avez plusieurs gestionnaires de transactions en place.
Quelques conseils..
Lors de l'utilisation de annotaion @EnableBatchProcessing, Spring Batch enregistre automatiquement un gestionnaire de transactions , et votre JpaTransactionManager peut-être jamais utilisé.
Si vous souhaitez modifier le gestionnaire de transactions que spring batch, vous devez implémenter l'interface BatchConfigurer.(https://blog.codecentric.de/en/2013/06/spring-batch-2-2-javaconfig-part-3-profiles-and-environments/).
Vous pouvez spécifier le gestionnaire de transactions pour les tasklets comme suit:
OriginalL'auteur Sinto K Itteera
Ce genre de problèmes se produisent avec les anciennes version de java comme jdk 6 ou plus de versions inférieures.Mise à niveau de votre version de jdk 7 ou au-dessus. Même moi, je n'avais même un peu la question avant qui disparu lorsque j'ai mis à jour ma version de jdk 7.
OriginalL'auteur Jeevitha
J'ai été en mesure de résoudre un problème similaire, par la mise en œuvre d'un ressort lot de configuration de JPA
Cela a été copié à partir de:https://github.com/hantsy/spring4-sandbox/blob/master/batch-jpa/src/main/java/com/hantsylabs/example/spring/config/JpaBatchConfigurer.java
OriginalL'auteur mad_fox