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 :

Participez à la FAQ Spring [FAQ]


Sujet :

Spring Java

  1. #1
    Rédacteur

    Avatar de Mickael Baron
    Homme Profil pro
    Ingénieur de Recherche en Informatique
    Inscrit en
    Juillet 2005
    Messages
    14 974
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche en Informatique
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2005
    Messages : 14 974
    Points : 72 947
    Points
    72 947
    Par défaut Participez à la FAQ Spring
    Bonjour,

    La FAQ Spring est ouverte à tous, vous pouvez donc y participer activement. Soit vous pouvez poster vos questions et réponses dans cette enfilade, soit vous pouvez utiliser l'application collaborative d'édition de FAQ.

    L'adresse de la FAQ : http://java.developpez.com/faq/spring/

    Merci à tous pour vos contributions.

    L'équipe Java
    Responsable Java de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Java, consulter la page cours
    N'hésitez pas à consulter la FAQ Java et à poser vos questions sur les forums d'entraide Java
    --------
    Ingénieur de Recherche en informatique au LIAS / ISAE-ENSMA
    Page de Developpez.com : mbaron.developpez.com
    Twitter : www.twitter.com/mickaelbaron
    Blog : mickael-baron.fr
    LinkedIn : www.linkedin.com/in/mickaelbaron
    DBLP : dblp.uni-trier.de/pers/hd/b/Baron:Micka=euml=l

  2. #2
    Membre du Club

    Inscrit en
    Janvier 2006
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 44
    Points : 64
    Points
    64
    Par défaut Comment maintenir la session hibernate dans la vue pour utiliser le lazy loading
    Si la Session Factory d'hibernate est géré par Spring il est alors possible d'utiliser un filtre mis à disposition par le framework Spring.

    Ce filtre commit la transaction après le traitement par la servlet (ou l'action de votre framework préféré), puis recommence une transaction pour la présentation de la jsp ou la techno de vue de votre choix.

    Une fois la page rendue le filtre ferme la session. Cette stratégie est aussi utilisé par le framework JBoss Seam.

    On configure le filtre dans web.xml :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <filter>
    	<filter-name>Hibernate Session In View Filter</filter-name>
           <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>Hibernate Session In View Filter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>

  3. #3
    Invité
    Invité(e)
    Par défaut Comment accéder aisément au contexte d'application.
    L'interface ApplicationContextAware est reconnue par Spring qui y injecte automatiquement le contexte de l'application courante via la méthode setApplicationContext(ApplicationContext context)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class MyClass implement ApplicationContextAware {
     
      ApplicationContext context;
     
      public void setApplicationContext(ApplicationContext context ){
        this.context = context;
      }
     
      public AnotherClass getAnotherBean() {
        return (AnotherClass) context.getBean("anotherBean");
      }
     
    }

  4. #4
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Points : 6 301
    Points
    6 301
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  5. #5
    Membre du Club

    Inscrit en
    Janvier 2006
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 44
    Points : 64
    Points
    64
    Par défaut c'est pas recommandé
    Je désapprouve l'utilisation de cette interface car on est couplé avec Spring.

  6. #6
    Expert éminent
    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
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour.
    Spring 2.5 offre enfin une nouvelle méthode d'intégration avec JSF compatible avec la version 1.2 (qui ne repose pas sur le VariableResolver, déprécié depuis JSF 1.2).

    une mise à jour de la Q/R Comment utiliser Spring avec JSF ?
    serait d'ajouter ce bout de code dans faces-config.xml:

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <application> 
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver 
      </el-resolver> 
    </application>

    Le reste fonctionne exactement de la même façon qu'avec le DelegatingVariableResolver.

  7. #7
    Membre habitué
    Avatar de Righetto Dominique
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mai 2002
    Messages : 81
    Points : 149
    Points
    149
    Par défaut Comment intégrer EhCache et Spring ?
    Pour intégrer EhCache et Spring afin de pouvoir injecter directement un bean Cache, on définit le bean ci-dessous dans un des fichiers de définitions du contexte Spring :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <bean id="customCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    		<property name="cacheManager">
    			<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    				<property name="configLocation"
    					value="classpath:ehcache.xml" />
    				<property name="shared" value="false" />
    			</bean>
    		</property>
    		<property name="cacheName" value="SampleConfigOne" />
    	</bean>
    On place la valeur de la propriété cacheName sur le nom d'une des définitions de cache effecutées dans le fichier ehcache.xml.

    Dans cette déclaration, on précise que le fichier de définition des caches se trouve dans le classpath au niveau de la racine (on pourrait également utiliser
    classpath*:ehcache.xml pour lui indiquer de chercher ce fichier dans tous les classpath). On précise également que le CacheManager n'est pas partagé via la propriété shared.

    Ensuite on peut injecter ce bean normalement dans tout bean qui en aurait besoin via :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <bean ...>
         <property name="cache" value="customCache" />
    </bean>
    Geek inside

  8. #8
    Membre habitué
    Avatar de Righetto Dominique
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mai 2002
    Messages : 81
    Points : 149
    Points
    149
    Par défaut Comment intégrer Oracle Toplink et Spring ?
    Pour intégrer Oracle Toplink et Spring il faut déclarer un bean "sessionFactory" dans lequel on va préciser :
    • L'endroit où se trouve le fichier de session qui contient lui même l'endroit où se trouve le descripteur de mapping
    • La source de données
    • Le logger

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <bean id="sessionFactory" class="org.springframework.orm.toplink.LocalSessionFactoryBean">
    		<property name="configLocation" value="toplink-sessions.xml"/>
    		<property name="dataSource" ref="dataSource"/>
    		<property name="sessionLog">
    			<bean class="org.springframework.orm.toplink.support.CommonsLoggingSessionLog"/>
    		</property>
    </bean>
    Dans cet exemple on indique que :
    • Le fichier de session Toplink se trouve à la racine du classpath de l'application
    • La source de données est un bean déja défini et nommé "dataSource"
    • Le logger est CommonsLogging et il est géré par Spring


    Voici le contenu de mon fichier de session "toplink-sessions.xml" qui indique que le fichier de mapping "toplink-Mapping.xml" est lui aussi à la racine du classpath de l'application :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <?xml version="1.0" encoding="UTF-8"?>
    <toplink-sessions version="10g Release 3 (10.1.3.0.0)" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <session xsi:type="server-session">
          <name>Session</name>
          <event-listener-classes/>
          <primary-project xsi:type="xml">toplink-Mapping.xml</primary-project>      
       </session>
    </toplink-sessions>
    Ensuite pour utiliser ce bean "sessionFactory" il suffit d'hériter de la classe "org.springframework.orm.toplink.support.TopLinkDaoSupport"
    et d'utiliser le ToplinkTemplate via "getTopLinkTemplate()" pour executer des traitements.

    Exemple de classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class MonDaoImpl extends TopLinkDaoSupport implements MonDao {
    //Placer les méthodes utilisant "getTopLinkTemplate()" ici...
    }
    Configuration de cette classe dans Spring :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <bean id="monDao" class="com.drighetto.dao.impl.MonDaoImpl">
    	<property name="sessionFactory" ref="sessionFactory" />
    </bean>
    Note : Il faut enlever dans le fichier de mapping Toplink les informations de connexion à la base de données sinon Spring indique qu'il y à un conflit et de ce fait il n'arrive pas à créer une instance du bean "sessionFactory".
    Geek inside

  9. #9
    Membre habitué
    Avatar de Righetto Dominique
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mai 2002
    Messages : 81
    Points : 149
    Points
    149
    Par défaut Comment accéder au contexte Spring depuis un composant non géré par Spring ?
    Pour donner accés au contexte Spring aux composants non gérés par Spring, il suffit d'implémenter un bean géré par Spring qui va exposer des méthodes d'accés au contexte Spring.

    Exemple de bean exposant des méthodes d'accés au contexte 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
     
    package com.drighetto.essai.springcontextaware;
     
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
     
    /**
     * Spring Bean Provider - Retrieve a bean in the Spring context and give access
     * to Spring context for the bean non managed by Spring
     * 
     * @author Dominique RIGHETTO
     */
    public class SpringBeanProvider implements ApplicationContextAware {
     
    	/** Spring context */
    	private static ApplicationContext SPRING_CTX = null;
     
    	/**
             * 
             * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
             * 
             * {@inheritDoc}
             */
    	public void setApplicationContext(ApplicationContext ctx)
    			throws BeansException {
    		SPRING_CTX = ctx;
    	}
     
    	/**
             * Method (shortcut) to retrieve a bean from Spring context
             * 
             * @param beanName
             *            Name of the bean in the context
             * @return a object
             */
    	public static Object getBean(String beanName) {
    		return SPRING_CTX.getBean(beanName);
    	}
     
    	/**
             * Method to access to Spring context
             * 
             * @return a reference to the Spring context
             */
    	public static ApplicationContext getSpringContext() {
    		return SPRING_CTX;
    	}
     
    }
    Remarque : Dans cet exemple on donne accés au contexte en autorisant les actions de modifications sur le contexte Spring et les beans en donnant une référence directe sur ces derniers et non un clone.

    Voici la déclaration du bean d'exposition dans la configuration 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
     
    <?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:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
     
    	<!-- ==============================   BEANS   ============================= -->
    	<!-- Bean provider -->
    	<bean id="springBeanProvider"	class="com.drighetto.essai.springcontextaware.SpringBeanProvider" />
     
    	<!-- Simple Spring managed bean used by the example below -->
    	<bean id="simplePojo"
    		class="com.drighetto.essai.springcontextaware.SimplePojo">
    		<property name="message" value="Hello World" />
    	</bean>
    </beans>
    Voici un exemple d'utilisation :
    La classe "com.drighetto.essai.springcontextaware.SimplePojo" est une simple classe avec un attribut nommé "message" de type "String" avec des getter/setter...
    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
     
    	/**
             * Entry point
             * @param args Command line
             */
    	public static void main(String[] args) {
    		try {
    			// Initialize a Spring context
    			ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
     
    			// Get a Spring Bean from the bean provider and display value...
    			SimplePojo simplePojoInstance = (SimplePojo) SpringBeanProvider.getBean("simplePojo");
    			System.out.printf("Value of POJO message : %s\n", simplePojoInstance.getMessage());
    			System.out.printf("Number of bean in the context : %s\n",SpringBeanProvider.getSpringContext().getBeanDefinitionCount());
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    La sortie à l'execution de l'exemple est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Value of POJO message : Hello World
    Number of bean in the context : 2
    Geek inside

  10. #10
    Membre habitué
    Avatar de Righetto Dominique
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mai 2002
    Messages : 81
    Points : 149
    Points
    149
    Par défaut Comment intégrer Apache Axis2 et Spring ?
    Note : Cette réponse part du principe que le lecteur connaît Axis2 !

    Pour intégrer Apache Axis2 et Spring de maniére à ce que ce dernier gére les instances des web services,
    il faut déclarer le bean qui représente le web service dans le fichier de configuration du web service, c'est à dire dans le fichier "services.xml" via le tag "SpringBeanName" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <parameter name="SpringBeanName" locked="false">monBeanWebService</parameter>
    ET indiquer à Axis que c'est Spring qui est le fournisseur d'instances, cela se fait via le tag "ServiceObjectSupplier" dans le fichier "services.xml"

    Voici ces tags dans le fichier "services.xml" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <service name="MonService">
        <description>
            Mon super service
        </description>
        <messageReceivers>
            <messageReceiver
                mep="http://www.w3.org/2004/08/wsdl/in-out"
        		class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
        </messageReceivers>
        <parameter name="ServiceObjectSupplier" locked="false">org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier</parameter>
    <parameter name="SpringBeanName" locked="false">monBeanWebService</parameter>
        <parameter name="useOriginalwsdl">true</parameter>
    </service>
    Donc les lignes importantes dans ce fichier sont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    <parameter name="ServiceObjectSupplier" locked="false">org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier</parameter>
    <parameter name="SpringBeanName" locked="false">monBeanWebService</parameter>
    Car la premiére indique à Axis que c'est Spring qui est le fournisseur d'instances et la seconde quel bean Spring représente le service...

    "monBeanWebService" est un bean (une classe publique non abstraite non finale avec des méthodes publiques qui représentent les services exposés) qui est déclaré dans un fichier de configuration Spring.
    Geek inside

  11. #11
    Membre habitué
    Avatar de Righetto Dominique
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mai 2002
    Messages : 81
    Points : 149
    Points
    149
    Par défaut Comment intégrer JPA et Spring ?
    Voici les déclarations à effectuer pour intégrer JPA et Spring (cet exemple se base sur l'utilisation de l'implémentation Oracle Toplink de JPA) :

    Etape 1 : Déclaration dans le contexte Spring des dépendances JPA
    Activation du tissage lors du runtime pour le contexte Spring afin que tous les beans implémentant l'interface "LoadTimeWeaverAware" (comme le bean LocalContainerEntityManagerFactoryBean) reçoivent une référence vers le tisseur (cf documentation Spring pour plus de précisions)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <context:load-time-weaver />
    Déclaration du "PersistenceUnitManager" permettant de personnaliser la sélection des unités de persistences et des sources de données.
    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
     
    	<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    		<!-- On spécifie ici les lieux où trouver les fichiers de persistence -->
    		<property name="persistenceXmlLocations">
    			<list>
    				<value>classpath*:META-INF/persistence.xml</value>
    			</list>
    		</property>
    		<!-- On spécifie ici les sources de données à utiliser, locale ou distante -->
    		<property name="dataSources">
    			<map>
    				<entry key="localDataSource" value-ref="dataSource" />
    				<!--<entry key="remoteDataSource" value-ref="remote-db" />-->
    			</map>
    		</property>
    		<!-- On spécifie ici la sources de données par défaut si aucune source de données n''est disponible -->
    		<property name="defaultDataSource" ref="dataSource" />
    	</bean>
    Déclaration de l' "EntityManagerFactory" permettant de fournir les instances des gestionnaires d'entités
    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
     
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    		p:dataSource-ref="dataSource"
    		p:persistenceUnitManager-ref="persistenceUnitManager">
    		<!-- On spécifie ici l''adaptateur Spring pour l''implémentation JPA utilisée -->
    		<property name="jpaVendorAdapter">
    			<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter" p:databasePlatform="oracle.toplink.essentials.platform.database.oracle.OraclePlatform"
    				p:showSql="false" />
    		</property>
    		<!-- On spécifie ici le tisseur utilisée pour la modification du ByteCode, cf documentation de Spring pour plus de précisions -->
    		<property name="loadTimeWeaver">
    			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    		</property>
    		<!-- On spécifie ici le dialecte utilisé en fonction de l'' implémentation JPA utilisée -->
    		<property name="jpaDialect">
    			<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
    		</property>
    	</bean>
    Déclaration du "TransactionManager" qui est le gestionnaire de transaction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <bean id="txManager"
    class="org.springframework.orm.jpa.JpaTransactionManager"
    		p:entityManagerFactory-ref="entityManagerFactory">
    		<!-- On spécifie ici le dialecte utilisé en fonction de l'' implémentation JPA utilisée -->
    	<property name="jpaDialect">
                       <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
    	</property>
    </bean>
    Activation de la prise en compte des annotations de type @Required,@Autowired,@PostConstruct,@PreDestroy,@Resource,@PersistenceContext,@PersistenceUnit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <context:annotation-config />
    Déclaration d'un traducteur d'exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    Etape 2 : Implémentation d'une classe utilisant JPA
    Chaque classe qui désire utiliser JPA pour accéder aux données peut :
    • Soit hériter de la classe "org.springframework.orm.jpa.support.JpaDaoSupport"
    • Soit se faire injecter un attribut de type "org.springframework.orm.jpa.JpaTemplate"


    Dans le cas de l'héritage voici le type de déclaration à effectuer pour déclarer la classe (dépendance sur l' "EntityManagerFactory")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	<bean id="myDao" class="com.drighetto.springjpa.dao.impl.DaoJpaImpl"
    		p:entityManagerFactory-ref="entityManagerFactory" />
    Documentation de Spring sur JPA

    Note : Pour le moment l'utilisation de JPA avec Spring ne supporte que l'isolation par défaut pour l'isolation des transactions...
    Dans la classe org.springframework.orm.jpa.DefaultJpaDialect (la classe "org.springframework.orm.jpa.vendor.TopLinkJpaDialect" hérite de cette classe) dans la méthode beginTransaction() une vérification est faite sur l'isolation placée et si celle-ci n'est pas placée à défaut alors l'exception suivante est levée "Standard JPA does not support custom isolation levels - use a special JpaDialect for your JPA implementation".


    Voici le fichier de contexte dans son ensemble :
    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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!--
    	********************************************
    	Application context for the project
    	********************************************	
    -->
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:jee="http://www.springframework.org/schema/jee"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:util="http://www.springframework.org/schema/util"
    	xsi:schemaLocation="
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
    			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    			http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
     
     
     
     
    	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
     
    	<!--
    		Activates a load-time weaver for the context. Any bean within the context that
    		implements LoadTimeWeaverAware (such as LocalContainerEntityManagerFactoryBean)
    		will receive a reference to the autodetected load-time weaver.
    	-->
    	<context:load-time-weaver />
     
    	<!-- DataSource -->
    	<bean id="dataSource"
    		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
    		p:driverClassName="oracle.jdbc.driver.OracleDriver"
    		p:url="jdbc:oracle:thin:@localhost:1521:xe" p:username="MyTestUser"
    		p:password="MyTestUser" />
     
    	<!-- JNDI DataSource for JEE environments -->
    	<!--
    		<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
    	-->
     
    	<!-- JPA PersistenceUnitManager used to customize the selection of the persistence unit and the datasources -->
    	<bean id="persistenceUnitManager"
    		class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    		<!-- Multiple value can be specified here -->
    		<property name="persistenceXmlLocations">
    			<list>
    				<value>classpath*:META-INF/persistence.xml</value>
    			</list>
    		</property>
    		<property name="dataSources">
    			<map>
    				<entry key="localDataSource" value-ref="dataSource" />
    				<!--<entry key="remoteDataSource" value-ref="remote-db" />-->
    			</map>
    		</property>
    		<!-- if no datasource is specified, use this one -->
    		<property name="defaultDataSource" ref="dataSource" />
    	</bean>
     
    	<!-- JPA EntityManagerFactory -->
    	<bean id="entityManagerFactory"
    		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    		p:dataSource-ref="dataSource"
    		p:persistenceUnitManager-ref="persistenceUnitManager">
    		<property name="jpaVendorAdapter">
    			<bean
    				class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"
    				p:databasePlatform="oracle.toplink.essentials.platform.database.oracle.OraclePlatform"
    				p:showSql="false" />
    		</property>
    		<property name="loadTimeWeaver">
    			<bean
    				class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    		</property>
    		<property name="jpaDialect">
    			<bean
    				class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
    		</property>
    	</bean>
     
    	<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) -->
    	<bean id="txManager"
    		class="org.springframework.orm.jpa.JpaTransactionManager"
    		p:entityManagerFactory-ref="entityManagerFactory">
    		<property name="jpaDialect">
    			<bean
    				class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
    		</property>
    	</bean>
     
     
     
     
    	<!-- ========================= CONFIG DEFINITIONS ========================= -->
     
    	<!--
    		Activates various annotations to be detected in bean classes: Spring's
    		@Required and @Autowired, as well as JSR 250''s @PostConstruct,
    		@PreDestroy and @Resource (if available) and JPA's @PersistenceContext
    		and @PersistenceUnit (if available).
    	-->
    	<context:annotation-config />
     
    	<!-- Exception translation bean post processor -->
    	<bean
    		class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
     
     
     
     
    	<!-- ================================== TRANSACTIONS DEFINITIONS ================================== -->
    	<!-- For the moment JPA only support ISOLATION_DEFAULT for the transaction isolation -->
     
    	<!-- Define pointcut for txAdvices -->
    	<aop:config>
    		<!-- DAO Layer -->
    		<aop:advisor advice-ref="txAdviceDao"
    			pointcut="execution(* com.drighetto.springjpa.dao.impl.*.*(..))" />
    		<!-- Service Layer -->
    		<aop:advisor advice-ref="txAdviceService"
    			pointcut="execution(* com.drighetto.springjpa.services.*.*(..))" />
    	</aop:config>
     
    	<!-- the transactional advice for DAO layer -->
    	<tx:advice id="txAdviceDao" transaction-manager="txManager">
    		<!-- the transactional semantics... -->
    		<tx:attributes>
    			<!-- Read methods don't use a transaction -->
    			<tx:method name="read*" propagation="SUPPORTS"
    				read-only="true" />
    			<!-- Exclude Getter/Setter -->
    			<tx:method name="set*" propagation="SUPPORTS"
    				read-only="true" />
    			<tx:method name="get*" propagation="SUPPORTS"
    				read-only="true" />
    			<!-- All others methods must use a existing transaction -->
    			<tx:method name="*" isolation="DEFAULT" timeout="10"
    				propagation="MANDATORY" read-only="false"
    				rollback-for="org.springframework.dao.DataAccessException" />
    		</tx:attributes>
    	</tx:advice>
     
    	<!-- the transactional advice for Service layer -->
    	<tx:advice id="txAdviceService" transaction-manager="txManager">
    		<!-- the transactional semantics... -->
    		<tx:attributes>
    			<!-- Read methods don't use a transaction -->
    			<tx:method name="display*" propagation="SUPPORTS"
    				read-only="true" />
    			<!-- Exclude Getter/Setter -->
    			<tx:method name="set*" propagation="SUPPORTS"
    				read-only="true" />
    			<tx:method name="get*" propagation="SUPPORTS"
    				read-only="true" />
    			<!-- All others methods create a transaction -->
    			<tx:method name="*" isolation="DEFAULT" timeout="10"
    				propagation="REQUIRES_NEW" read-only="false"
    				rollback-for="org.springframework.dao.DataAccessException" />
    		</tx:attributes>
    	</tx:advice>
     
     
     
     
    	<!-- ================================== BEANS DEFINITIONS ================================== -->
     
    	<!-- DAO -->
    	<bean id="myDao" class="com.drighetto.springjpa.dao.impl.DaoJpaImpl"
    		p:entityManagerFactory-ref="entityManagerFactory" />
     
    	<!-- Service -->
    	<bean id="myService"
    		class="com.drighetto.springjpa.services.Processor"
    		p:myDao-ref="myDao" />
     
    </beans>
    Geek inside

  12. #12
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Points : 6 301
    Points
    6 301
    Par défaut Comment fermer un contexte d'application en détruisant les Beans ?
    Lors de l'utilisation de Spring en dehors d'un contexte Web, il est intéressant de fermer proprement un contexte d'application, en libérant les resources et les beans.

    La méthode close() de l'interface ConfigurableApplicationContext permet de faire cela.
    Il faut donc que l'implémentation du contexte d'application Spring implémente cette interface, et heureusement c'est le cas de ClasspathXmlApplicationContext, qui est dans doute la version la plus utilisée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ConfigurableApplicationContext context = new ClasspathApplicationContext("com/developpez/hikage/context/applicationContext.xml");
     
    // Termine le contexte Spring
    context.close();
    Attention cependant, seul les beans de scope singleton seront détruits.


    Une autre méthode de ConfigurableApplicationContext qui peut s'avérer utile est registerShutdownHook().
    Cette méthode permet de spécifier à la JVM de fermer automatiquement le contexte Spring lorsque l'application s'arrête.
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  13. #13
    Membre habitué
    Avatar de Righetto Dominique
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mai 2002
    Messages : 81
    Points : 149
    Points
    149
    Par défaut Comment utiliser JRuby avec Spring ?
    L'objectif recherché est d'utiliser dans une application Java/JEE des implémentations JRuby de certains interfaces définis en java.

    Deux approches sont possibles :
    1. Soit l'implémentation JRuby se trouve dans le fichier de configuration Spring
    2. Soit l'implémentation JRuby se trouve dans un fichier de script


    Pour expliquer les deux cas nous allons configurer dans Spring les implémentations de l'interface com.drighetto.springjruby.ActionDefinition dont le code est ci-dessous :
    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
     
    package com.drighetto.springjruby;
     
    import java.io.IOException;
     
    /**
     * Interface defining some actions
     * 
     * @author Dominique RIGHETTO <dominique.righetto@gmail.com>
     * 
     */
    public interface ActionDefinition {
     
    	/**
             * Method to write content to a file
             * 
             * @param content
             *            Content
             * @param filename
             *            Name of the target file with the full path
             * @throws IOException
             */
    	void writeContent(String content, String filename) throws IOException;
     
    	/**
             * Method to read the content to a file
             * 
             * @param filename
             *            Name of the target file with the full path
             * @return The file content as a String
             * @throws IOException
             */
    	String readContent(String filename) throws IOException;
     
    	/**
             * Method to obtain the last method called
             * 
             * @return a message
             */
    	String obtainLastMethodCalled();
     
    }
    L'espace de nommage utilisé ici est "lang", ce dernier nécessite la déclaration suivante dans les fichiers de configuration Spring :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <?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:lang="http://www.springframework.org/schema/lang"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd">
    ...
    </beans>
    Cas 1 : l'implémentation JRuby se trouve dans le fichier de configuration Spring
    Voici la configuration Spring associée :
    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
     
    	<lang:jruby id="actionDefinitionInline" script-interfaces="com.drighetto.springjruby.ActionDefinition">
    		<lang:inline-script>
    			#Needed to use java
    			require 'java'
     
    			#JRuby implementation of the "com.drighetto.springjruby.ActionDefinition" Java interface
    			class ActionDefinitionJRubyImpl
     
    			  #Indicate that this JRuby class implement the "com.drighetto.springjruby.ActionDefinition" Java interface
    			  include com.drighetto.springjruby.ActionDefinition
     
    			  #Define instance attribute accessor
    			  attr_reader :last_called_method
     
    			  #Constructor        
    			  def initialize()
    			    @last_called_method = ""
    			  end
     
    			  #Explicit Java Style Setter method required by Spring !!!
    			  def setLast_called_method(text)
    			    @last_called_method  = text
    			  end 
     
    			  #Implementation of the writeContent() method
    			  def writeContent(content, filename)
    			    my_file = File.new(filename, "w")
    			    my_file.puts content
    			    my_file.close
    			    @last_called_method  = "writeContent() on #{filename}"
    			  end
     
    			  #Implementation of the readContent() method
    			  def readContent(filename)
    			    content = ""    
    			    my_file = File.new(filename, "r")
    			    while (line = my_file.gets)
    			      content = content + line      
    			    end
    			    my_file.close
    			    @last_called_method  = "readContent() on #{filename}"
    			    return content
    			  end
     
    			  #Implementation of the obtainLastMethodCalled() method
    			  def obtainLastMethodCalled()
    			    return @last_called_method
    			  end
     
    			end		
    		</lang:inline-script>
    		<lang:property name="last_called_method" value="No method called" />		
    	</lang:jruby>
    Voici la description des attributs du tag "lang:jruby" :
    • id : Nom du bean Spring
    • script-interfaces : Nom complet de l'interface implémenté

    Le tag "lang:inline-script" sert à placer le corps du script
    Le tag "lang:property" sert à injecter des valeurs dans le script JRuby


    Cas 2 : l'implémentation JRuby se trouve dans un fichier de script
    Voici la configuration Spring associée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	<lang:jruby id="actionDefinition" refresh-check-delay="5000" scope="prototype"
    		script-interfaces="com.drighetto.springjruby.ActionDefinition"
    		script-source="classpath:/jruby/action_definition_jruby_impl.rb">
    		<lang:property name="last_called_method" value="No method called" />
    	</lang:jruby>
    Voici la description des attributs du tag "lang:jruby" :
    • id : Nom du bean Spring
    • refresh-check-delay : Delai entre lequel Spring va vérifier si le script à été modifié, attention cette vérification ne se fait que lorsque le bean est utilisé, ce n'est pas une tâche récurrente planifiée...
    • scope : Portée du bean (singleton ou prototype)
    • script-source: Chemin vers le fichier de script, il est possible d'utiliser les spécifications de chemins offertes par Spring pour l'accés aux ressources (filesystem, classpath,...)
    • script-interfaces : Nom complet de l'interface implémenté

    Le tag "lang:property" sert à injecter des valeurs dans le script JRuby

    Voici le contenu du script "action_definition_jruby_impl.rb"

    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
     
    #Needed to use java
    require 'java'
     
    #JRuby implementation of the "com.drighetto.springjruby.ActionDefinition" Java interface
    class ActionDefinitionJRubyImpl
     
      #Indicate that this JRuby class implement the "com.drighetto.springjruby.ActionDefinition" Java interface
      #-> Optional in Spring : If is not specified Spring will use the interface defined in the XML config declaration
      #-> Mandatory in pure JRuby
      #include com.drighetto.springjruby.ActionDefinition
     
      #Define instance attribute accessor
      attr_reader :last_called_method
     
      #Constructor        
      def initialize()
        @last_called_method = ""
      end
     
      #Explicit Java Style Setter method required by Spring !!!
      def setLast_called_method(text)
        @last_called_method  = text
      end 
     
      #Implementation of the writeContent() method
      def writeContent(content, filename)
        my_file = File.new(filename, "w")
        my_file.puts content
        my_file.close
        @last_called_method  = "writeContent() on #{filename}"
      end
     
      #Implementation of the readContent() method
      def readContent(filename)
        content = ""    
        my_file = File.new(filename, "r")
        while (line = my_file.gets)
          content = content + line      
        end
        my_file.close
        @last_called_method  = "readContent() on #{filename}"
        return content
      end
     
      #Implementation of the obtainLastMethodCalled() method
      def obtainLastMethodCalled()
        return @last_called_method
      end
     
    end
     
    #Instantiate and return a new instance of the ActionDefinitionJRubyImpl class
    #Note from the Spring documentation : 
    #  If you forget to do this, it is not the end of the world; this will however 
    #result in Spring having to trawl (reflectively) through the type representation of 
    #your JRuby class looking for a class to instantiate. 
    #  In the grand scheme of things this will be so fast that you'll never notice it, but 
    #it is something that can be avoided by simply having a line such as the one above as 
    #the last line of your JRuby script. If you don't supply such a line, or if Spring cannot 
    #find a JRuby class in your script to instantiate then an opaque ScriptCompilationException
    #will be thrown immediately after the source is executed by the JRuby interpreter.
    ActionDefinitionJRubyImpl.new
    Ensuite aprés avoir configuré le bean on peut l'utiliser de maniére transparente dans un autre bean ou dans une classe via l'interface définie en java.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //Récupération de l'instance du bean
    ActionDefinition actionDefinition = (ActionDefinition) applicationContext.getBean("actionDefinition");
     
    //Utilisation normale
    actionDefinition.writeContent(.....);
    Rubrique dédiée dans la documentation Spring

    Cet exemple ayant été réalisé avec Maven2, voici la liste des dépendances :
    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
     
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring</artifactId>
    			<version>2.5.3</version>
    		</dependency>
    		<dependency>
    			<groupId>log4j</groupId>
    			<artifactId>log4j</artifactId>
    			<version>1.2.9</version>
    		</dependency>
    		<dependency>
    			<groupId>org.jruby</groupId>
    			<artifactId>jruby-complete</artifactId>
    			<version>1.0.3</version>
    		</dependency>
    		<dependency>
    			<groupId>cglib</groupId>
    			<artifactId>cglib-nodep</artifactId>
    			<version>2.1_3</version>
    		</dependency>
    	</dependencies>
    Geek inside

  14. #14
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Points : 6 301
    Points
    6 301
    Par défaut Puis-je utiliser Spring gratuitement dans mon projet ?
    Oui

    Spring Framework ainsi que la plupart des projets du portfolio Spring sont distribués sous licence Apache 2.0.

    L'utilisation de ces projets au sein d'un développement est donc complètement libre et gratuite.
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  15. #15
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Points : 6 301
    Points
    6 301
    Par défaut Comment injecter des dépendances dans une servlet ?
    Depuis Spring 2.5.1, une nouvelle classe utilitaire est disponible : SpringBeanAutowiringSupport

    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
     
     
    public class MaServlet extends HttpServlet {
     
      //Spring 3.0
      @Inject
      private MonService service;
     
      @Autowired
      private MonService service2;
     
      @Resource
      private MonService service3;
     
      @Override
      public void init() {
        SpringBeanAutowiringSupport.
          processInjectionBasedOnCurrentContext(this);
      }
    }
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  16. #16
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut Résoudre le problème "No Hibernate Session bound to thread"
    Le problème vient du fait qu'Hibernate a besoin d'effectuer les opérations que vous lui demandez dans une transaction.

    D'habitude, tout se fait de manière automatique pour peu que vous ayez bien configuré votre fichier application-context.xml en y indiquant un transactionManager et un proxyTransactionnel (cf de nombreux tutoriels que l'on peut trouver sur google).

    TRADUCTION D'UN FORUM ANGLOPHONE : DEBUT

    D'un autre coté, il se peut que vous ayez besoin d'exécuter un bout de code hors du proxy transactionnel, et dans ce cas la méthode habituelle suivante ne marche plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Session session = sessionFactory.getCurrentSession();
     
    try {
        session.beginTransaction();
        // do stuff...
        session.getTransaction().commit();
    catch(Exception ex) {
        session.getTransaction().rollback();
    }
    En effet elle ne peut être utilisée lorsque la SessionFactory est configurée via LocalSessionFactoryBean. A la place il faut s'arranger pour que Spring gère lui même les problèmes de transaction.

    Soit en 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
    17
    18
    <!-- define which methods --> 
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="create" />
            <tx:method name="update" />
            <tx:method name="delete" />
            <tx:method name="find" read-only="true" />
        </tx:attributes>
    </tx:advice>
     
    <!-- define which classes -->
    <aop:config>
        <aop:pointcut id="serviceOperation" expression="execution(* my.services.*Service.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
    </aop:config>
     
    <!-- this bean will have automatic transaction management -->
    <bean id="foobar" class="my.services.FooBarService" />
    soit au sein du code:
    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
    ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
     
    PlatformTransactionManager txManager = (PlatformTransactionManager) appContext.getBean("transactionManager");
     
    TransactionTemplate txTemplate = new TransactionTemplate(txManager);
     
    txTemplate.execute(new TransactionCallback() {
     
        public Object doInTransaction(TransactionStatus status) {
            try {
                // do stuff here...
            } finally {
                status.setRollbackOnly();
            }
     
            return null;
        }
    });

    TRADUCTION D'UN FORUM ANGLOPHONE : FIN


    Commentaire: faire les choses au sein du code est hideux, car on instancie des classes de Spring, ce qui est contraire à la philosophie de Spring.

    En ce qui me concerne, j'ai abouti à une solution à mi chemin: via application.xml, j'injecte le transactionManager défini dans spring dans ma classe java. Puis à partir de là je fais le reste dans le code.

    SOURCE
    Mes cours sur l'écosystème Java EE - N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 141
    Points : 178
    Points
    178
    Par défaut La SessionFactory Par annotation ou fichiers properties Testez et tenez moi au courant merci!
    Bonjour, Peut-on avoir une intégration de Spring dans Hibernate sans utiliser les fichiers de configurations des 2 frameworks? mais soir en utilsant les fichiers properties soit une annotation? Pourquoi Spring n'a pas pensé à créer une simple annotation pour dans son intégration à Hibernate puis une classe créant l'insatnce d'une SessionFactory, ce qui permet de rendre l'utilisation d'une couche Dao sans configurer la SessionFactory dans le contexte? J'ai une solution. Elle consiste à créer une classe créant l'instance de la SessionFactory puis soit utiliser des fichiers properties soit utiliser une annotation. Merci de la tester et me donner votre avis:
    La classe qui permet de créer la SessionFactory est 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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
     
    public class SWESessionFactory extends AnnotationSessionFactoryBean{
    	private static final Log log = LogFactory.getLog(SWESessionFactory.class);
    	/*Le nom du fichier de properties contenant les classes*/
    	private String annotatedClassesPropertiesFile="annotatedClasses.properties";
    	/*Nom du fichier properties pour la connexion en base de données*/
    	private String dataBasePropertiesFile="databaseProperties.properties";
    	/*Nom du fichier properties pour les propriétés d'hibernate*/
    	private String hibernatePropertiesFile="hibernateProperties.properties";
    	/**
             * 
             */
    	public SWESessionFactory() {
    		// TODO Auto-generated constructor stub
    		super();
    	}
    	/**
             * 
             * @param byProperties : si vrai alors la configuration doit être faite par
             * fichiers properties, faux on utilisation l'annotation SWEFactory
             * @return une instance de la session Factory
             */
    	public final SessionFactory configure(boolean byProperties){
    		if(byProperties)return propertiesConfiguration();
    		return annotatedConfiguration();
    	}
    	/**
             * 
             * @return une instance de la session factory prêt à l'emploi
             * avec une configuration avec des fichiers properties
             */
    	@SuppressWarnings("rawtypes")
    	private final SessionFactory propertiesConfiguration(){
    		log.debug("Initialisation de la sessionFactory par les fichiers de Properties");
    		List<Class> classes = null;
    		Class[] annotatedClasses;
    		classes=loadClasses();
    		annotatedClasses=classes.toArray(new Class[classes.size()]);
    		setAnnotatedClasses(annotatedClasses);
    		setHibernateProperties(loadPropertiesFile(hibernatePropertiesFile));
    		setDataSource(loadDataSource(null));
    		try {
    			log.debug("Chargement de la session Factory");
    			return buildSessionFactory();
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			log.error("Le chargement de la session Factory a échoué");
    			throw new SWEException("Impossible de localiser la SessionFactory",e);
    		}
    	}
    	/**
             * 
             * @return une instance de la session factory prêt à l'emploi
             * Dans ce cas on impose à la classe Dao d'être annotée
             */
    	@SuppressWarnings({ "unchecked", "rawtypes" })
    	private final SessionFactory annotatedConfiguration(){
    		log.debug("Initialisation de la session Factory avec les annotations");
    		StackTraceElement stes[]=Thread.currentThread().getStackTrace();
    		SWEFactory swef=null;
    		for(StackTraceElement ste:stes){
    			String className=ste.getClassName();
    			Class c=null;
    			try {
    				log.debug("Détermination de la classe courrente");
    				c=getClass().getClassLoader().loadClass(className);
    			} catch (ClassNotFoundException e) {
    				log.debug("On ne passe pas ici");
    				e.printStackTrace();
    			}
    			if(c.isAnnotationPresent(SWEFactory.class)){
    				swef=(SWEFactory) c.getAnnotation(SWEFactory.class);
    				log.debug("La classe courrente a été trouvée il déclare bien l'annotation SWEFactory :"+swef);
    				break;
    			}
    		}
    		setAnnotatedClasses(swef.annotatedClasses());
    		Properties p=new Properties();
    		PropertyDataSource pdss[]=swef.dataSource();
    		for(PropertyDataSource pds:pdss)p.setProperty(pds.key().name(), pds.value());
    		setDataSource(loadDataSource(p));
    		p.clear();
    		HibernateProperties hps[]=swef.hibernateProperties();
    		for(HibernateProperties hp:hps)	p.setProperty(hp.key(), hp.value());
    		setHibernateProperties(p);
    		try {
    			log.debug("Chargement de la session Factory");
    			return buildSessionFactory();
    		} catch (Exception e) {
    			log.error("Le chargement de la session Factory a échoué");
    		throw new SWEException("Impossible de localiser la SessionFactory",e);
    		}
    	}
    	/**
             * 
             * @param annotatedClassesPropertiesFile: préciser le nom du fichier properties pour les classes
             */
    	public void setAnnotatedPropertiesFile(String annotatedClassesPropertiesFile){
    		this.annotatedClassesPropertiesFile=annotatedClassesPropertiesFile;
    	}
    	/**
             * 
             * @param dataBasePropertiesFile: préciser le nom du fichier properties pour la dataBaseProperties 
             */
    	public void setDataBasePropertiesFile(String dataBasePropertiesFile){
    		this.dataBasePropertiesFile=dataBasePropertiesFile;
    	}
    	/**
             * 
             * @param hibernatePropertiesFile: préciser le nom du fichier properties hibernate
             */
    	public void setHibernatePropertiesFile(String hibernatePropertiesFile){
    		this.hibernatePropertiesFile=hibernatePropertiesFile;
    	}
    	/**
             * 
             * @return la liste des classes annotées dans le fichier properties
             */
    	@SuppressWarnings("rawtypes")
    	private final List<Class> loadClasses(){
    		List<Class> classes=new ArrayList<Class>();
    		Properties p=null;
    		log.debug("Localisons du fichier de properties "+annotatedClassesPropertiesFile);
    		p = loadPropertiesFile(annotatedClassesPropertiesFile);
    		Set<Entry<Object,Object>> set=p.entrySet();
    		Iterator<Entry<Object,Object>> it=set.iterator();
    		while(it.hasNext()){
    			Entry<Object,Object> en=it.next();
    			Class<?> c;
    			String cls=en.getValue().toString();
    			try {
    				log.debug("Mise à jour de la classe "+cls);
    				c = Class.forName(cls);
    			} catch (ClassNotFoundException e) {
    				log.error("La classe "+cls+" n'existe pas");
    				throw new SWEException("La classe "+cls+" n'existe pas",e);
    			}
    			classes.add(c);
    		}
    		return classes;
    	}
    	/**
             * @param p: contient les propriétés de la base de données qui peut provenir soit
             * du fichier properties sot de l'annotation
             * @return l'instance de la DataSource qui nous permettra  d'établir une connexion 
             * à la base de données
             */
    	private final DriverManagerDataSource loadDataSource(Properties p){
    		DriverManagerDataSource dataSource=new DriverManagerDataSource();
    		p=p==null?loadPropertiesFile(dataBasePropertiesFile):p;
    		dataSource.setDriverClassName(p.getProperty("driverClassName"));
    		dataSource.setPassword(p.getProperty("password"));
    		dataSource.setUrl(p.getProperty("url"));
    		dataSource.setUsername(p.getProperty("username"));
    		dataSource.setConnectionProperties(p);
    		return dataSource;
    	}
    	private final Properties loadPropertiesFile(String name){
    		InputStream in=getClass().getClassLoader().getResourceAsStream(name);
    		Properties p=new Properties();
    		try {
    			p.load(in);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return p;
    	}
    }
    Cette classe peut être utilisée soit par des fichiers properties soit par une annotation dont le code est le suivant:
    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
     
    @Retention(RetentionPolicy.RUNTIME)
    @Target ({ElementType.TYPE})
    @Inherited
    public @interface SWEFactory {
    	@SuppressWarnings("rawtypes")
    	public Class[] annotatedClasses();
    	public PropertyDataSource[] dataSource();
    	public HibernateProperties[] hibernateProperties();
    	public @interface PropertyDataSource{
    		public enum KEY {url,username,password,driverClassName};
    		public KEY key();
    		public String value();
    	}
    	public @interface HibernateProperties{
    		public String key();
    		public String value();
    	}
    Testez le sur une couche Dao et tenez moi au courant
    Merci!

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 12
    Points : 15
    Points
    15
    Par défaut Comment externaliser des propriétés dans un fichier Properties ?
    Je voudrais juste ajouter une petite précision à cette FAQ.
    Il faudrait simplement préciser que cela fonctionne si on charge le contexte Spring dans un ApplicationContext. Ca ne fonctionne pas si on utilise directement une BeanFactory. Cette précision pourrait être utile pour les débutants à mon sens.

  19. #19
    Nouveau membre du Club

    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Points : 31
    Points
    31
    Par défaut
    Grosse contribution de ma part : la version pdf et hors ligne de la faq ne semble pas fonctionner ! J'en aurais besoin pour la lire dans le train Merci !

  20. #20
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Points : 6 301
    Points
    6 301
    Par défaut
    Corrigé

    Merci de l'infos
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

Discussions similaires

  1. Participez à la FAQ JDBC
    Par Mickael Baron dans le forum JDBC
    Réponses: 7
    Dernier message: 23/09/2013, 17h26
  2. Participez à la FAQ Struts
    Par Mickael Baron dans le forum Struts 1
    Réponses: 3
    Dernier message: 05/04/2007, 22h00
  3. [Participez à la FAQ !] La question de la semaine
    Par Giovanny Temgoua dans le forum Langage
    Réponses: 18
    Dernier message: 13/12/2005, 09h58
  4. Participez à la FAQ Java EE
    Par Mickael Baron dans le forum Java EE
    Réponses: 1
    Dernier message: 28/08/2003, 11h49

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