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 :

org.hibernate.LazyInitializationException no session or session was closed lors de l'execution d'un test Junit


Sujet :

Spring Java

  1. #1
    Candidat au Club
    Inscrit en
    Février 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2012
    Messages : 4
    Points : 4
    Points
    4
    Par défaut org.hibernate.LazyInitializationException no session or session was closed lors de l'execution d'un test Junit
    Bonjour tout le monde,

    Je développe une application avec Spring et Hibernate mais je ne connais pas très bien aucun des technologies. J'ai un problème que je n'arrive pas à résoudre malgré les dizaines d'entrées sur le net.
    J'obtiens une org.hibernate.LazyInitializationException depuis un test Junit lors de l'accès à un attribut de mon entité, cet attribut est chargé en mode lazy.

    Voici les éléments que je peux vous fournir afin que vous pussiez m'aider:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Entity
    @Table(name = "rejeu_commande")
    public class Order implements Serializable {
     
    ...
     
    @OneToMany(mappedBy = "order", targetEntity = com.francetelecom.facade.hibernate.model.EtaskOrder.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
     @JoinColumn(name = "order_id")
     private List<EtaskOrder> etaskOrders;
     
    ....
    }
    Et voici la classe Junit :
    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
    package com.francetelecom.facade.services.findAndGetCustomerOrder.manager;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:spring/applicationContext-test.xml" })
    public class FindAndGetOrderManagerTestCase extends AbstractJUnit4SpringContextTests{
     
    
     @Autowired
     private FindAndGetOrderManager testedClass;
     @Autowired
     private ReplayOrderRepository replayOrderRepository;
    
     
    
    
     @Test
     public void testCreateOrder() throws RepositoryException, OrderException, TranscoException {
      
      long idOrderFacades=10000107000000004L;
      String erreurInjection = "98";
      
      Order order= replayOrderRepository.getOrderById(idOrderFacades);
      CreateCustomerOrder customerOrder =replayOrderRepository.getCreateCustomerOrderFromDB(order);
      FacadeOrder facadeOrder = new FacadeOrder();
    
      order.getEtaskOrders();
      FindAndGetOrder findAndGetorder = testedClass.createOrder(customerOrder, order, false);
      
      assertEquals(idOrderFacades, findAndGetorder.getIdFacades());
      assertEquals(facadeOrder.getOffreCompose(), findAndGetorder.getContract());
      //assertEquals(facadeOrder.getInternalId(),findAndGetorder.getParsifalOrderId())
      assertEquals(facadeOrder.getParsifalOrderId(),findAndGetorder.getParsifalOrderId());
      assertEquals(facadeOrder.getCreationDate(), findAndGetorder.getCreationDate());
      
      //String statusCode = String.valueOf(findAndGetRepository.getFindAndGetOrderManager().computeLocalStatusCode(order.getWorkflowStatus()).getCode());
            //assertEquals(statusCode,findAndGetorder.getStatusCode());
      
      assertEquals(facadeOrder.getSource(),findAndGetorder.getReferential());
      assertFalse(findAndGetorder.isDetails());
      
      assertEquals(erreurInjection, findAndGetorder.getLocalRejectionCause());
    
     }
    Lors de l’accès a etaskorders j'obtiens l'exception LazyInitializationException dont la trace complète 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
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.facade.hibernate.model.Order.etaskOrders, no session or session was closed
     at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
     at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
     at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)
     at org.hibernate.collection.PersistentBag.isEmpty(PersistentBag.java:255)
     at com.francetelecom.facade.order.FacadeOrder.populateWorkflowInformationWithDatabaseData(FacadeOrder.java:1523)
     at com.francetelecom.facade.services.findAndGetCustomerOrder.manager.FindAndGetOrderManager.createOrder(FindAndGetOrderManager.java:59)
     at com.francetelecom.facade.services.findAndGetCustomerOrder.manager.FindAndGetOrderManagerTestCase.testCreateOrder(FindAndGetOrderManagerTestCase.java:101)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
     at java.lang.reflect.Method.invoke(Method.java:592)
     at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
     at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
     at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
     at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
     at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
     at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
     at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
     at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
     at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
     at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
     at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Comment je peux eviter ce problème?

    La solution consistant à définir le fetch pour eTaskOrders comme fetch = FetchType.EAGER n'est pas possible à cause de prérequis applicatives.

    Merci d'avance pour votre aide
    Aurea

  2. #2
    Candidat au Club
    Inscrit en
    Février 2012
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2012
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    J'ai trouvée une solution, si ça peut aider d'autres avec ce problème

    Changement de la classe extendée par ma classe de test à AbstractTransactionalJUnit4SpringContextTests

    Ajout de la notation @Transactional à ma méthode de test.

    Voici le code resultat:

    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
    package com.francetelecom.facade.services.findAndGetCustomerOrder.manager;
     
    import static org.junit.Assert.*;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.transaction.annotation.Transactional;
     
     
    import com.francetelecom.facade.hibernate.exception.TranscoException;
    import com.francetelecom.facade.hibernate.model.Order;
    import com.francetelecom.facade.order.FacadeOrder;
    import com.francetelecom.facade.order.exception.OrderException;
     
    import com.francetelecom.facade.replay.ReplayOrderRepository;
    import com.francetelecom.facade.replay.RepositoryException;
    import com.francetelecom.facade.services.findAndGetCustomerOrder.FindAndGetOrder;
    import com.orange.crm.CreateCustomerOrder;
     
     
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:spring/applicationContext-test.xml" })
     
    public class FindAndGetOrderManagerTestCase extends AbstractTransactionalJUnit4SpringContextTests{
     
     
    	@Autowired
    	private FindAndGetOrderManager testedClass;
    	@Autowired
    	private ReplayOrderRepository replayOrderRepository;
     
    	@Test
    	@Transactional
    	public void testCreateOrder() throws RepositoryException, OrderException, TranscoException {
     
    		long idOrderFacades=10000107000000004L;
    		String erreurInjection = "98";
     
    		Order order= replayOrderRepository.getOrderById(idOrderFacades);
    		CreateCustomerOrder customerOrder =replayOrderRepository.getCreateCustomerOrderFromDB(order);
    		FacadeOrder facadeOrder = new FacadeOrder();
     
    		FindAndGetOrder findAndGetorder = testedClass.createOrder(customerOrder, order, false);
     
    		assertEquals(idOrderFacades, findAndGetorder.getIdFacades());
    		assertEquals(facadeOrder.getOffreCompose(), findAndGetorder.getContract());
    		//assertEquals(facadeOrder.getInternalId(),findAndGetorder.getParsifalOrderId())
    		assertEquals(facadeOrder.getParsifalOrderId(),findAndGetorder.getParsifalOrderId());
    		assertEquals(facadeOrder.getCreationDate(), findAndGetorder.getCreationDate());
     
    		//String statusCode = String.valueOf(findAndGetRepository.getFindAndGetOrderManager().computeLocalStatusCode(order.getWorkflowStatus()).getCode());
            //assertEquals(statusCode,findAndGetorder.getStatusCode());
     
    		assertEquals(facadeOrder.getSource(),findAndGetorder.getReferential());
    		assertFalse(findAndGetorder.isDetails());
     
    		assertEquals(erreurInjection, findAndGetorder.getLocalRejectionCause());
     
    	}
     
     
    }

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Points : 1 745
    Points
    1 745
    Par défaut
    Pour ton test OK, mais tu risque d'avoir le même problème lorsqu'une application web utilisera ton EJB.

  4. #4
    Membre expérimenté Avatar de slim
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2002
    Messages
    938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2002
    Messages : 938
    Points : 1 337
    Points
    1 337
    Par défaut
    Citation Envoyé par Mathieu.J Voir le message
    Pour ton test OK, mais tu risque d'avoir le même problème lorsqu'une application web utilisera ton EJB.
    Exactement. Par contre, il ne s'agit pas d'un EJB. C'est un DAO (@REpository) ou un Service spring ? Aurea ne précise pas...

    Si la classe testée est un DAO, je pense qu'il faudrait plutôt voir du côté de la session hibernate. Vérifier si la session est toujours ouverte quand le flush se produit.
    Si c'est un service Spring, il faudrait mettre l'annotation @Transactionnal sur le service.
    Faites une recherche sur le forum et/ou sur internet et lisez la doc officielle avant de poser une question svp.
    et n'oubliez pas de lire les FAQ !
    FAQ Java et les cours et tutoriels Java
    Doc JAVA officielle
    AngularJS 1.x
    Angular 2

    Do it simple... and RTFM !

  5. #5
    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
    Lorsque tu veux tester une classe avec JUnit, la solution n'est pas d'utiliser @Transactional, elle répond pas à ce que tu voudras faire.
    La vraie question à poser est de savoir si ta Dao est transactionelle?si oui donc ton soucis vient de ton fetching qui doit être sûrement mal configuré. Sinon il faut plutôt utiliser l'annotation @TransactionConfiguration qui te gère des transactions provisoires pendant des tests unitaires. Maintenant c'est "le role de ton service de gérer la transaction" dans ton application web, et là il te faut un pattron de conception du genre OpenSessionInView ou OpenEntityManagerInView pour regler ton soucis.

Discussions similaires

  1. Réponses: 8
    Dernier message: 13/08/2014, 17h42
  2. Réponses: 1
    Dernier message: 30/03/2013, 14h53
  3. Réponses: 3
    Dernier message: 13/07/2011, 10h42
  4. Réponses: 4
    Dernier message: 11/04/2008, 12h12

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