IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Persistance des données Java Discussion :

Le @Transactional fonctionne au niveau DAO mais pas Service


Sujet :

Persistance des données Java

  1. #1
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut Le @Transactional fonctionne au niveau DAO mais pas Service
    Bonjour à tous,

    J'ai un petit bug que je ne comprend pas.

    Mon appli possède trois couche : Web, Service et DAO.

    Quand je mets le @Transactional dans mon service, ça ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Service
    class MonService 
     
      @autowired
      private ChienDao chienDao;
     
      @Transactional
      public void createMonChien(String name) {
        Chien chien = new Chien(name);
        chienDao.save(chien);
      }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Repository
    class ChienDao {
     
      @PersistenceContext
      private EntityManager entityManager;
     
     
      public void save(Chien chien) {
        entityManager.persist(chien);
      }
    Par contre, quand je mets le @Transactional dans le DAO (et que je l'enlève du service), ça marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @Service
    class MonService 
     
      @autowired
      private ChienDao chienDao;
     
      //@Transactional
      public void createMonChien(String name) {
        Chien chien = new Chien(name);
        chienDao.save(chien);
      }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    @Repository
    class ChienDao {
     
      @PersistenceContext
      private EntityManager entityManager;
     
      @Transactional     // la ca marche
      public void save(Chien chien) {
        entityManager.persist(chien);
      }
    Donc je ne comprend pas.
    J'aurais tendance à penser que ma config est bonne puisque ça marche quand je mets l'annotation dans le DAO...
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Un problème de configuration du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <context:component-scan ...
    peut-être ?

  3. #3
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    Dans mon applicationContext.xml, j'ai mis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...>
    	<context:component-scan base-package="com.masociete.monprojet" />
     
    	<import resource="db.xml" />
    	...
    mon db.xml :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    <?xml version="1.0" encoding="UTF-8"?>
    <beans ... default-autowire="byName">
     
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    		<property name="persistenceUnitName" value="MyBoPU" />
    	</bean>
     
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory" />
    	</bean>
     
    	<tx:annotation-driven />
     
    	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    </beans>

    et MonService est bien dans un package qui va bien (je crois) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    package com.masociete.monprojet.service.foo;
    ...
    Et puis, ça fonctionne quand je met l'annotation dans le DAO...
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  4. #4
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    Pour info, j'ai trouvé ce qui emperchait mon code de fonctionner. Je crois que je comprend vaguement pourquoi mais ça reste flou.

    En gros, pour que l'annotation fonctionne, il faut la placer sur une méthode appelée par un composant directement.

    Dans mon cas, je faisais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    @Service
    class MonService 
     
      @autowired
      private ChienDao chienDao;
     
      @Transactional
      public void createMonChien(String name) {
        Chien chien = new Chien(name);
        chienDao.save(chien);
      }
     
      public void appel() {
        createMonChien("milou");
        ...
      }
    et j'ai un composant qui appelle ça depuis la couche Web :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Component
    public class MonManager {
     
      @autowired
      private MonService monService;
     
      public String foo() {
        monService.appel();
        ...
      }
     
    }
    En fait, ça marche si c'est carrément foo() que j'annote :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    @Service
    class MonService 
     
      @autowired
      private ChienDao chienDao;
     
      //@Transactional
      public void createMonChien(String name) {
        Chien chien = new Chien(name);
        chienDao.save(chien);
      }
     
      @Transactional
      public void appel() {
        createMonChien("milou");
        ...
      }
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

  5. #5
    Membre confirmé
    Avatar de Khaled.Noordin
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 354
    Points : 497
    Points
    497
    Billets dans le blog
    1
    Par défaut
    Salut
    Mais est ce que tu pense pas que l'annotation de transaction n'a finalement pas de raison d’être sur le DAO, mais uniquement sur le service, quelque part ce te donne des DAO qui peuvent se passer d'import spring puisque @Repository("monDao") peut etre remplacé par un @Named("monDao") et devenir facilement des ejb et le sous classant et en décorant la sous classe par un @Stateless ou un @transactionnal pour un pojo spring et en plus si tu annote ton DAO avec un @Default et créer un qualifier l'injection style CDI est effective avec le conteneur IoC spring avec un minimum de xml puisque component scan ainsi injecter ton DAO dans ton service spring
    Enfin je dis ça, c'est juste histoire de papoter

  6. #6
    Rédacteur
    Avatar de thierryler
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    4 078
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 078
    Points : 12 815
    Points
    12 815
    Par défaut
    Au départ j'ai mis ça dans les DAO pour aller vite, en gardant en tête de les mettre dans les services, ce qui est fait maintenant.

    Pour tout dire à propos de CDI. Quand j'ai commencé le projet, je voulais faire du seam 3 mais je n'ai pas réussi à faire tout ce que je voulais. Je précise que je suis sous Tomcat. J'ai abandonné cette idée, heureusement. Ensuite je me suis limité à Weld et j'étais assez content. Mais après j'ai investi pas mal d’énergie sur Spring-security avec ldap/base/rechargement de droits/etc. Du coup je me suis contenté de spring + spring-security et j'ai viré Weld.

    Mais je suis à la recherche d'une bonne solution pour remplacer mon couple spring/spring-security par quelque chose utilisant CDI...

    Je suis aussi preneur d'un candidat pour remplacer JSF2/pretty-faces/prime-faces, qui irait avec le nouveau couple CDI
    Thierry Leriche-Dessirier
    Consultant Java JEE Web Agile freelance
    Rédacteur pour Developpez
    Professeur de Génie Logiciel à l'ESIEA

    Site : http://www.icauda.com / Linked'in : http://www.linkedin.com/in/thierryler / Twitter : @ThierryLeriche

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/12/2006, 17h20
  2. Programme VB6 fonctionne en XP SP1, mais pas en SP2
    Par domb_st dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 11/08/2006, 21h16
  3. Mon script fonctionne avec un bouton, mais pas avec l'image!
    Par julien.63 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 12/04/2006, 16h26
  4. Réponses: 9
    Dernier message: 08/03/2006, 12h27
  5. Réponses: 4
    Dernier message: 27/09/2005, 22h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo