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

Spring Java Discussion :

Propagation en Full annotation


Sujet :

Spring Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut Propagation en Full annotation
    Bonjour à tous,

    Débutant en spring et hibernate je profite de ce sujet pour vous faire part d'un problème lié aux transactions (en espérant ne pas me tromper de post ..)

    J'utilise Spring 2.5.5 ,hibernate 3.2.1.ga , mysql et Tomcat


    //interface de mon service
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       public interface IFaxService {
              public IFaxModel saveFaxModel(IFaxModel faxModel);
       }
    //implémentation de mon service
    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
    19
    20
     
         @Service("faxServiceTarget")
         @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
          public class FaxService implements IFaxService {
     
                   private IFaxDao faxDao;
     
                    @Autowired
                    public void setFaxDao(@Qualifier("faxDao") IFaxDao faxDao) {
                        this.faxDao = faxDao;
                    }
     
                    public IFaxDao getFaxDao() {
                        return faxDao;
                    }
     
                    public IFaxModel saveFaxModel(IFaxModel faxModel) {
                         return getFaxDao().saveFaxModel(faxModel);
                    }
          }
    l'objet qui utilise mon service

    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
     
    public class TestFaxFactory{
        private IFaxService faxService;
     
         @Autowired
         public void setFaxService(@Qualifier("faxService") IFaxService faxService) {
            this.faxService = faxService;
         }
         public IFaxService getFaxService() {
            return faxService;
        }
     
         public void testSaveFaxMod(){
                  IFaxModel faxModel_1 = (IFaxModel) getXmlBeanFactory().getBean("faxModel_1");
                  faxModel_1 = getFaxService().saveFaxModel(faxModel_1);
     
           }
         }
    mon fichier de conf spring

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tool" xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                               http://www.springframework.org/schema/util
                               http://www.springframework.org/schema/util/spring-util-2.0.xsd
                               http://www.springframework.org/schema/context
                               http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
     
        <context:annotation-config/>
        <context:component-scan base-package="fax"/>
     
        <bean id="faxDao" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="proxyInterfaces" value="fax.dao.IFaxDao"/>
            <property name="interceptorNames">
                <list>
                    <value>faxDaoInterceptor</value>
                    <value>faxDaoBean</value>
                </list>
            </property>
        </bean>
     
     <bean id="faxService" parent="transactionProxy">
            <property name="target" ref="faxServiceTarget"/>
            <property name="transactionAttributeSource">
                <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
            </property>
        </bean>
     
     
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref local="sessionFactory"/>
            </property>
        </bean>
     
     
        <bean id="transactionProxy" abstract="true"
              class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager" ref="transactionManager"/>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
     
     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
              scope="singleton">
            <property name="configLocation" value="classpath:test.hibernate.cfg.xml"/>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.c3p0.autoCommitOnClose">true</prop>
                    <prop key="hibernate.autoCommitOnClose">true</prop>
                    <prop key="hibernate.autocommit">true</prop>
                    <prop key="hibernate.connection.release_mode">auto</prop>
                    <prop key="hibernate.transaction.auto_close_session">true</prop>
                </props>
            </property>
        </bean>
    </beans>

    avec cette configuration le faxModel que je sauve est effectivement bien sauvé en base (je peux le voire via MySql browser ... )

    Je voudrais avoir le moins possible de xml dans mon fichier spring. (d'ou les annotation dans mes classes)

    Mes questions sont donc les suivantes :

    Y a t il un moyen (annotations particulières , méthodes ou classes à implémenter ... ) pour ne pas avoir à définir les morceaux de codes suivant de mon fichier de conf spring :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      <bean id="faxService" parent="transactionProxy">
            <property name="target" ref="faxServiceTarget"/>
            <property name="transactionAttributeSource">
                <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
            </property>
        </bean>
    et même dans l'absolue si il y a un moyen de ne pas avoir a définir dans le fichier de conf de spring la description du transactionProxy et du transactionManager

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
       <bean id="transactionProxy" abstract="true"
              class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager" ref="transactionManager"/>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref local="sessionFactory"/>
            </property>
        </bean>
    j'ai bien essayé d'injecter directement mon service "faxServiceTarget" dans mon objet de test de la manière suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class TestFaxFactory {
     
    [...]
     @Autowired
        public void setFaxService(@Qualifier("faxServiceTarget") IFaxService faxService) {
            this.faxService = faxService;
    [..]
        }
    mais en faisant de la sorte, je n'ai plus de transaction et bien que je n'ai aucune erreur, mon faxModel n'est pas sauvegardé en base...

    Une âme charitable aurait elle à défaut d'une solution , une piste à me proposer ?

    MErci d'avance !

  2. #2
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Salut,
    Tu peux regarder ce billet blog qui présente comment mettre un truc pareil en place (avec JPA), mais la partie gestion des transactions est quasiment la même.

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    les tests ne sont-ils pas rollback par défaut ?

    si vous voulez des tests "persistants" : voir AbstractTransactionalSpringContextTests at setComplete();

  4. #4
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    tout d'abord merci pour la rapidité de vos réponses ...
    Je vais regarder de suite le lien que djo.mos m'a fourni ...

    petite remarque pour JeitEmgie

    les tests ne sont-ils pas rollback par défaut ?

    si vous voulez des tests "persistants" : voir AbstractTransactionalSpringContextTests at setComplete();
    Il ne me semble pas que cela soit le cas, car quand je défini mon transaction manager dans mon fichier xml de spring j'ai bien des données dans ma base aprèss le lancement du test ...

    encore merci à tous les deux pour votre participations
    a+

  5. #5
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Re bonjour,

    Salut,
    Tu peux regarder ce billet blog qui présente comment mettre un truc pareil en place (avec JPA), mais la partie gestion des transactions est quasiment la même.
    Cet article est très interressant mais apparement il se conclu par une question de Baptiste Wicht qui correspond exactement à ma propre question .. :

    Commentaire de: Baptiste Wicht [Membre] · http://baptiste-wicht.developpez.com
    Salut

    Je me demandais : Si on utilise Spring sans XML (avec le scanner de bean definition et les annotations), il y a un moyen de configuration les transactions ?

    Le problème est surtout pour activer sans le XML ? Ou alors, est-ce qu'il y a moyen d'utiliser en même temps le scanner et un fichier XML ?
    Permalien 16/04/2009 @ 15:02

    J'ai aussi trouvé ce post : http://blog.developpez.com/wichtoune...e-exhaustive-/ ecrit justement par Baptiste Wicht, mais quelques questions restent pour moi sans réponse :

    l'exemple que fourni Batiste (j'espère qu'il ne m'en voudras pas de l'appeler par son prénom ) est celui ci :


    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
    @Configuration(defaultLazy = Lazy.TRUE) 
    @ImportXML("classpath:test/datasource-config.xml") 
    @ComponentScan("test.services") 
    @AnnotationDrivenTx(transactionManager="txManager") 
    public class ApplicationConfig { 
      @Bean 
      public Bar bar() { 
      return new Bar(); 
      } 
     
      @Bean 
      public PlatformTransactionManager txManager() { 
      return new DataSourceTransactionManeger(dataSource()); 
      } 
    }
    il y précise ceci :

    @AnnotationDrivenTx(transactionManager="txManager") : Permet d'utiliser Spring transaction avec les annotations et de déclarer le transaction manager.
    Mais ou doit se définir ce fameux "txManager" ???? Dans le fichier de conf de Spring ? dans une classe ?

    Ai-je raté une étape , ai-je mal compris un truc ? dois je voire ca directement avec lui ou bien ce poste fera l'affaire ?

    Si vous pouvez éclairer ma lanterne ca serait très sympathique

    merci d'avance pour votre participation

  6. #6
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    comme me l'a fait si bien remarqué Batiste l'info était juste en dessous :

    Il est déclaré en Java juste en dessous :

    @Bean
    public PlatformTransactionManager txManager() {
    return new DataSourceTransactionManager(dataSource());
    }

    JavaConfig va prendre les méthodes annotées avec @Bean et les transformer en un bean du nom de la méthode (txManager ici)

  7. #7
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    J'ai donc mis en place la méthode de ce très sympathique Mr Baptiste Wicht mais je me retrouve une fois de plus dans l'impasse avec une belle exeception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Error creating bean with name 'transactionProxy': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'target' is required
    ma classe de config étant la suivante :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    @Configuration(defaultLazy = Lazy.TRUE)
    @ComponentScan("fax")
    @ImportXml(locations = "applicationContext-fax2u-test.xml")
    @AnnotationDrivenTx(transactionManager = "transactionManager")
     
    public class ApplicationConfigTest {
     
     
        @Bean
        public ProxyFactoryBean faxService() {
            ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
            try {
                proxyFactoryBean.setProxyInterfaces(new Class[]{IFaxService.class});
                proxyFactoryBean.setInterceptorNames(new String[]{"faxServiceInterceptor", "faxServiceBean"});
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return proxyFactoryBean;
        }
     
        @Bean
        public TransactionProxyFactoryBean faxServiceBean() {
            TransactionProxyFactoryBean transactionProxyFactoryBean = transactionProxy();
            transactionProxyFactoryBean.setTarget("faxServiceTarget");
            transactionProxyFactoryBean.setTransactionAttributeSource(new AnnotationTransactionAttributeSource());
     
            return transactionProxyFactoryBean;
        }
     
        @Bean
        public HibernateTransactionManager transactionManager() {
            HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager();
            hibernateTransactionManager.setSessionFactory(sessionFactory());
            return hibernateTransactionManager;
        }
     
        @Bean()
        public TransactionProxyFactoryBean transactionProxy() {
            TransactionProxyFactoryBean transactionProxyFactoryBean = new TransactionProxyFactoryBean();
            transactionProxyFactoryBean.setTransactionManager(transactionManager());
            Properties properties = new Properties();
            properties.put("*", "PROPAGATION_REQUIRED");
            transactionProxyFactoryBean.setTransactionAttributes(properties);
            return transactionProxyFactoryBean;
        }
     
        @Bean(scope = "singleton")
        public SessionFactory sessionFactory() {
            AnnotationSessionFactoryBean annotationSessionFactoryBean = new AnnotationSessionFactoryBean();
            annotationSessionFactoryBean.setConfigLocation(new ClassPathResource("test.hibernate.cfg.xml"));
            Properties props = new Properties();
            props.put("hibernate.c3p0.autoCommitOnClose", true);
            props.put("hibernate.autoCommitOnClose", true);
            props.put("hibernate.autocommit", true);
            props.put("hibernate.connection.release_mode", "auto");
            props.put("hibernate.transaction.auto_close_session", true);
            annotationSessionFactoryBean.setHibernateProperties(props);
            try {
                annotationSessionFactoryBean.afterPropertiesSet();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return annotationSessionFactoryBean.getConfiguration().buildSessionFactory();
        }
    }
    et mon test tout bête est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    JavaConfigApplicationContext  applicationContextTest = new JavaConfigApplicationContext(ApplicationConfigTest.class);

    Au départ j'avai le fichier Xml suivant ( qui fonctionnait !!) :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    [...]
    <!--=========================== FAX SERVICE ==================================-->
     
        <bean id="faxService" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="proxyInterfaces" value="fax.services.pub.IFaxService"/>
            <property name="interceptorNames">
                <list>
                    <value>faxServiceInterceptor</value>
                    <value>faxServiceBean</value>
                </list>
            </property>
        </bean>
     
     
        <bean id="faxServiceBean" parent="transactionProxy">
            <property name="target" ref="faxServiceTarget"/>
            <property name="transactionAttributeSource">
                <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
            </property>
        </bean>
        <!--=========================== TRANSACTION ==================================-->
     
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref local="sessionFactory"/>
            </property>
        </bean>
     
     
        <bean id="transactionProxy" abstract="true"
              class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager" ref="transactionManager"/>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
        <!--=========================== SESSSION FACTORY ==================================-->
     
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
              scope="singleton">
            <property name="configLocation" value="classpath:test.hibernate.cfg.xml"/>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.c3p0.autoCommitOnClose">true</prop>
                    <prop key="hibernate.autoCommitOnClose">true</prop>
                    <prop key="hibernate.autocommit">true</prop>
                    <prop key="hibernate.connection.release_mode">auto</prop>
                    <prop key="hibernate.transaction.auto_close_session">true</prop>
                </props>
            </property>
        </bean>
     
    [...]
    Je me demande si le problème n'est pas lié à la traduction de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     <bean id="faxServiceBean" parent="transactionProxy">
            <property name="target" ref="faxServiceTarget"/>
            <property name="transactionAttributeSource">
                <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
            </property>
        </bean>
    en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      @Bean
        public TransactionProxyFactoryBean faxServiceBean() {
            TransactionProxyFactoryBean transactionProxyFactoryBean = transactionProxy();
            transactionProxyFactoryBean.setTarget("faxServiceTarget");
            transactionProxyFactoryBean.setTransactionAttributeSource(new AnnotationTransactionAttributeSource());
     
            return transactionProxyFactoryBean;
        }
    Remarque : je ne sais pas comment "traduire" le
    parent="transactionProxy" de <bean id="faxServiceBean" parent="transactionProxy">
    dans mon bean faxServiceBean()

    en èsperant que quelqu'un qui aura eu le courage de tout lire aura une réponse ou une idée à me proposer

Discussions similaires

  1. FULL ACCESS Vs ACCESS-MSDE
    Par Maxence HUBICHE dans le forum Sondages et Débats
    Réponses: 54
    Dernier message: 18/06/2005, 17h22
  2. [FLASH MX] Effet de zoom full dynamique
    Par yoda_style dans le forum Flash
    Réponses: 8
    Dernier message: 23/10/2004, 13h11
  3. Problème de TABLE ACCESS FULL
    Par elitost dans le forum Administration
    Réponses: 14
    Dernier message: 25/09/2004, 12h37
  4. Remplacer FULL OUTER JOIN
    Par funrighd dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/07/2004, 10h54
  5. Recherche FULL Text existe que dans MySql ?
    Par seb.49 dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 01/06/2004, 22h30

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