web-dev-qa-db-fra.com

Hibernate JPA et Spring javax.persistence.TransactionRequiredException: aucune transaction n'est en cours

Quand j'appelle: 

entityManager.flush()

Je reçois l'exception mentionnée dans le titre.

J'utilise Hibernate JPA.

23
kcheng

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.

16
Roman

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.

4
Chandra Sekar S

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"/>

3
Mannie

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.

2

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 {

}
2
Yamir Abdiel Ortega

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;
}
1
markdsievers

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';
}
1
Dapeng

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 .

1
debugs-bunny

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.

0
Maciej Biłas

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.

0
chro

J'ai finalement corrigé cette erreur en ajoutant

<tx:annotation-driven mode="aspectj" transaction-manager="yourTransactionManager" />

dans mon application-context.xml

0
Firzen

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.

0
Nestor Urquiza

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 .

0
Jason Gritman