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 :

@Transactional et gestion des sessions hibernate


Sujet :

Spring Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut @Transactional et gestion des sessions hibernate
    Bonjour,

    Voudrais utiliser l'annotation @Transactional pour gérer mes transactions Hibernate.

    Cependant, je suis obligé d'appeler la méthode openSession() car getCurrentSession() lève une exception.
    Je voudrais savoir si cela est normal et quel peut être l'impact pour la gestion du pool de session.

    Le problème est que actuellement, mes données ne sont pas insérées en base. Je n'ai aucune exception, juste aucune données, comme si il était de ma responsabilité de faire le commit, ce qui ne devrait pas être le cas.

    Voici mon DAO :
    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
     
    @Repository
    public class UserDaoImpl implements IUserDao {
     
    	@Inject
    	private SessionFactory sessionFactory;
     
    	@Override
    	public void create(UserModel user) throws TechnicalException {
    		UserEntity entity = UserTranslator.toEntity(user);
    		//Session session = sessionFactory.getCurrentSession();
    		Session session = sessionFactory.openSession();
     
    		session.persist(entity);
    		session.close();
    	}
     
    }
    Et 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
     
    @Service
    public class UserServiceImpl implements IUserService {
     
    	@Inject
    	private IUserDao userDao;
     
    	@Transactional
    	@Override
    	public void create(UserModel user) throws TechnicalException, BusinessException {
    		userDao.create(user);
    	}
     
    }

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Après de nombreuses recherches, j'ai enfin trouvé l'origine de l'erreur. Cela venait de ma configuration hibernate. En particulier, il ne faut pas affecter la valeur "thread" au paramètre "current_session_context_class".

    Voici la configuration complète de mon session factory :
    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
     
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="packagesToScan">
    			<list>
    				<value>myproject.dao.entity</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
    				<prop key="hibernate.show_sql">true</prop>
    				<prop key="hibernate.connection.pool_size">1</prop>
    				<prop key="hibernate.hbm2ddl.auto">create</prop>
    			</props>
    		</property>
    	</bean>

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    J'ai parlé trop vite. Mon test unitaire passe, mais pas en mode server.

    Cette fois, j'obtiens cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    org.hibernate.hibernateexception no session found for current thread
    Une question que je me pose. Est-ce qu'il ne devrait pas être nécessaire de faire de la configuration AOP ? Car je suppose que @Transactional fonctionne avec l'AOP.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Cette fois j'ai résolu mon problème pour de bon.

    Spring peut effectivement se baser sur l'AOP pour gérer les transactions hibernate, mais cela vient en substitution de l'annotation @Transactional. Donc mon problème ne venait pas de là. En fait, il faut ajouter un filter Spring dans le web.xml qui a pour responsabilité d'initialiser la session hibernate dans un thread local :
    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
     
    <filter>
    	<filter-name>hibernateFilter</filter-name>
    	<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    	<init-param>
    		<param-name>sessionFactoryBeanName</param-name>
    		<param-value>sessionFactory</param-value>
    	</init-param>
    </filter>
    <filter-mapping>
    	<filter-name>hibernateFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    	<dispatcher>REQUEST</dispatcher>
    	<dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    Par rapport à mon code, trois choses :
    - Annoter la classe de service avec @Transactional. En fait, l'annotation sur les méthodes est optionnelle, ce qui est obligatoire c'est d'annoter la classe.
    - Supprimer le paramètre "current_session_context_class"
    - Ajouter le filter Spring

    Si ça peut aider d'autres personnes

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Ce filtre est plutôt destiné à permettre à la vue d'accéder à la session Hibernate et d'éviter les erreurs de type LazyLoadingException.
    Tant mieux si ça a réglé ton problème, mais il semble quand même que ta conf ait un problème.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Oui effectivement cette solution a réglé mon problème.
    Tu penses que ma conf a un problème de quel ordre ?

  7. #7
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Disons que j'ai déjà utilisé l'annotation transactionnal sans problème et donc sans ce filtre.
    Pourrais tu nous montrer ta conf Spring ?

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Merci de passer du temps sur mon problème. Ma conf est éclatée en plusieurs fichiers, mais voici celle qui pose problème :
    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
     
    <?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:tx="http://www.springframework.org/schema/tx"
    	xmlns:jee="http://www.springframework.org/schema/jee"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    			http://www.springframework.org/schema/tx
    			http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    			http://www.springframework.org/schema/jee
    			http://www.springframework.org/schema/jee/spring-jee.xsd">
     
    	<tx:annotation-driven />
    	<jee:jndi-lookup id="dataSource" jndi-name="${datasource.jndi.name}" />
     
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="packagesToScan">
    			<list>
    				<value>myproject.dao.entity</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
    				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
    				<prop key="hibernate.connection.pool_size">${hibernate.connection.pool_size}</prop>
    				<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
    			</props>
    		</property>
    	</bean>
     
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
     
    </beans>
    Et voici les valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    datasource.jndi.name=jdbc/MyProjectDataSource
     
    hibernate.dialect=org.hibernate.dialect.MySQLDialect
    hibernate.show_sql=true
    hibernate.connection.pool_size=1
    hibernate.hbm2ddl.auto=create

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Base gestion des session et journaux de transaction
    Par rodbeck dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 14/01/2011, 13h13
  2. [Spring & Hibernate] Gestion des sessions Hibernate
    Par Fennec. dans le forum Hibernate
    Réponses: 5
    Dernier message: 26/08/2010, 16h42
  3. Hibernate/Spring : gestion des sessions
    Par herve91 dans le forum Hibernate
    Réponses: 5
    Dernier message: 13/05/2010, 11h15
  4. Gestion des sessions Hibernate
    Par schumi2k2 dans le forum Hibernate
    Réponses: 5
    Dernier message: 31/03/2009, 17h44
  5. Hibernate et la gestion des sessions
    Par ruff15 dans le forum Hibernate
    Réponses: 5
    Dernier message: 15/10/2008, 14h08

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