Quand j'appelle:
entityManager.flush()
Je reçois l'exception mentionnée dans le titre.
J'utilise Hibernate JPA.
Après avoir rencontré ce problème moi-même et passé quelques heures à essayer de le résoudre, j'ai finalement trouvé une raison à cela: Spring a un bogue et ne peut pas gérer les transactions avec l'annotation @Transactional
si la même classe a l'annotation @Service
pour les moyens d'auto-câblage.
Une fois que l'annotation @Service
a été supprimée de la classe de service en question et qu'un bean approprié a été déclaré dans la configuration XML:
<bean id="myService" class="com.example.myapp.service.MyServiceImpl" />
le problème est parti.
Cochez cette/ JIRA bug pour plus de détails.
Assurez-vous d'avoir une transaction active lors de l'exécution de cette instruction. Si vous utilisez JPA, utilisez EntityManager.getTransaction (). Begin (). Cela suppose que vous utilisez JPA en dehors d'une étendue de transaction JTA.
Si vous exécutez l'application dans un conteneur avec support JTA, vous pouvez également utiliser JTA UserTransaction pour gérer les transactions.
Mon problème était lié à la façon dont j'ai configuré l'élément <tx:annotation-driven/>
dans ma définition de contexte -
À l'origine, j'avais le tissage au temps de chargement activé (non connu) qui lisait <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
et supprimait simplement le 2e attribut - tout fonctionnait (cela prenait 2 heures de tête à cogner). Je crois que le deuxième élément concerne le stéréotype @Configurable, mais je peux laisser d'autres personnes (plus intelligentes) expliquer la différence et pourquoi on travaillerait et l'autre ne le ferait pas .. J'espère que cela aidera ...
définition de travail = <tx:annotation-driven transaction-manager="transactionManager"/>
Assurez-vous d'avoir une transaction active lors de l'exécution de cette instruction. Si vous utilisez JPA, utilisez EntityManager.getTransaction().begin()
. Cela suppose que vous utilisez JPA en dehors d'une étendue de transaction JTA.
J'ai eu ce problème, ajoutez simplement l'annotation @Transacctional non seulement sur la méthode, mais également dans la classe avec votre annotation @Service.
par exemple:
@Service
@Transactional
public class MyService {
}
Printemps 4.3.1/Hibernate 4.2.21
Ma configuration était composée à 100% de code Java sans documents hibernate ni spring xml (par exemple, context.xml, persistence.xml, etc.) Le problème était la EntityManagerFactory
que je passais à la TransactionManager
, voir la configuration ci-dessous dans la méthode transactionManager
.
@Configuration
@EnableTransactionManagement
public class HibernateConfiguration2 {
@Bean
public DataSource dataSource() {
return ...; // Build a basic datasource
}
@Bean
@Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setPackagesToScan("nz.co.mark");
entityManagerFactory.setPersistenceProviderClass(org.hibernate.ejb.HibernatePersistence.class);
return entityManagerFactory;
}
@Bean
@Autowired
public EntityManager entityManager(LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean) {
EntityManager em = localContainerEntityManagerFactoryBean.getNativeEntityManagerFactory().createEntityManager();
em.setFlushMode(FlushModeType.AUTO);
return em;
}
@Bean
@Autowired
public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean emf) throws Exception {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf.getObject());
// The below line would generate javax.persistence.TransactionRequiredException: no transaction is in progress
// transactionManager.setEntityManagerFactory(emf.getNativeEntityManagerFactory());
return transactionManager;
}
Assurez-vous que votre méthode de gestionnaire est déclarée comme étant public
@Transactional
@RequestMapping('/test')
public String doTest() {
// do your stuff here
return 'testview';
}
J'ai eu le même problème ... j'ai passé quelques heures jusqu'à ce que je trouve enfin la raison ... C'est une seule ligne de code qui a provoqué l'exception dans mon cas ...
Dans mon mvc-core-config.xml, la ligne suivante en était la raison:
<context:component-scan base-package="com.my.package.application" />
Après que j'ai changé comme suit, tout a encore fonctionné:
<context:component-scan base-package="com.my.package.application.controller" />
Je suppose donc que le balayage de tous mes packages d’application au lieu de mes classes @Controller pose le problème de @ harshal-waghmare mentionné dans son message à une autre réponse .
Assurez-vous que votre configuration de ressort comprend la ligne suivante:
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
mode
peut être proxy ou aspectj et transaction-manager
doit pointer vers votre gestionnaire de transactions.
J'ai tout fait comme une suite. Mon problème était avec la balise "import", il y a plusieurs racines de contexte comme servlet-context et root-context qui ne dépendent pas l'une de l'autre. Cela devient clair avec la vue Spring Explorer dans STS. Pas de JTA pour Tomcat.
Mon conseil serait universel: lancez Pet Clinic sur votre environnement, Comment exécuter Spring 3.0 PetClinic dans Tomcat avec JPA Soutenu par Hibernate ou générer avec un fichier de remplacement Roo et essayez de comparer vos configurations avec celles référencées.
J'ai finalement corrigé cette erreur en ajoutant
<tx:annotation-driven mode="aspectj" transaction-manager="yourTransactionManager" />
dans mon application-context.xml
Même chose m’arrivait avec spring 3.0.0/3.0.3. Les données persistaient dans MySQL à partir de JUnit mais pas à partir du serveur Tomcat. Après tant de travail, j'ai abandonné RESOURCE_LOCAL pour JTA.
Cela a marché pour moi http://erich.soomsam.net/2007/04/24/spring-jpa-and-jta-with-hibernate-and-jotm/ Il utilise JTA et dépend de JOTM.
Pour JBoss 4.0 et Hibernate, j'ai résolu ce problème en ajoutant des propriétés de gestionnaire de transactions à ma définition EntityManagerFactoryBean
:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="xaDs" />
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory
</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup
</prop>
</props>
</property>
J'ai trouvé la solution sur ce fil de discussion .