Hibernate: échec paresseusement initialiser une collection de rôle, pas de session ou la session a été fermée
Mon code:
@Test
public void testAddRoleAndAddUser() {
Role r = roleDao.findByProperty("name", "admin");
if(r == null) {
r = new Role();
r.setName("admin");
r.setDescription("Just administrator.");
roleDao.save(r);
}
User u = dao.get(1l);
Set<Role> roles = u.getRoleSet();
logger.debug("Roles is null: " + (roles == null));
roles.add(r);
dao.save(u);
}
13:39:41,041 d'ERREUR:
org.mise en veille prolongée.LazyInitializationException
échoué paresseusement initialiser un
collection de rôle:
xxx.de l'entité.de base.De l'utilisateur.roleSet, pas de
session ou la session a été fermée
org.mise en veille prolongée.LazyInitializationException:
échoué paresseusement initialiser un
collection de rôle:
xxx.de l'entité.de base.De l'utilisateur.roleSet, pas de
session ou la session a été fermée à
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
au
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionifnotconnected(AbstractPersistentCollection.java:372)
au
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
au
org.mise en veille prolongée.collection.PersistentSet.ajouter(PersistentSet.java:212)
au
sg.com.junglemedia.test.dao.impl.mise en veille prolongée.UserDaoTest.testAddRoleAndAddUser(UserDaoTest.java:40)
au
soleil.de réfléchir.NativeMethodAccessorImpl.invoke0(Native
La méthode) à
soleil.de réfléchir.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
au
soleil.de réfléchir.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
au
java.lang.de réfléchir.La méthode.invoke(la Méthode.java:597)
au
org.junit.les coureurs.de modèle.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
au
org.junit.interne.les coureurs.de modèle.ReflectiveCallable.exécuter(ReflectiveCallable.java:15)
au
org.junit.les coureurs.de modèle.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
au
org.junit.interne.les coureurs.des déclarations.InvokeMethod.évaluer(InvokeMethod.java:20)
au
org.junit.interne.les coureurs.des déclarations.RunBefores.évaluer(RunBefores.java:28)
au
org.junit.les coureurs.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
au
org.junit.les coureurs.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
au
org.junit.les coureurs.ParentRunner$3.exécuter(ParentRunner.java:193)
au
org.junit.les coureurs.ParentRunner$1.annexe(ParentRunner.java:52)
au
org.junit.les coureurs.ParentRunner.runChildren(ParentRunner.java:191)
au
org.junit.les coureurs.ParentRunner.l'accès$000(ParentRunner.java:42)
au
org.junit.les coureurs.ParentRunner$2.évaluer(ParentRunner.java:184)
au
org.junit.les coureurs.ParentRunner.exécuter(ParentRunner.java:236)
au
org.eclipse.jdt.interne.junit4.runner.JUnit4TestReference.exécuter(JUnit4TestReference.java:46)
au
org.eclipse.jdt.interne.junit.runner.TestExecution.exécuter(TestExecution.java:38)
au
org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
au
org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
au
org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.exécuter(RemoteTestRunner.java:390)
au
org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.principale(RemoteTestRunner.java:197)
Aider quelqu'un?
- Ce n'
save(u)
faire? Comment gérez-vous leSession
? Où voulez-vous ouvrir/fermer?
Vous devez vous connecter pour publier un commentaire.
Dans votre classe d'entité, lorsque vous déclarez une cartographie de l'utilisateur de rôles, essayez de spécifier le fetchType à la HÂTE. Quelque chose comme ceci:
Mise à JOUR:
Les derniers commentaires de cette réponse a me faire revenir sur cette. Il a été un moment depuis que j'ai répondu, quand j'ai commencé à travailler avec Hibernate. Ce que Rafael et Mukus dire sont raisonnables. Si vous avez une grande collection, vous ne devriez pas utiliser le chargement agressif. Conjointement sélectionne toutes les données mappées à votre entrée et à la charge de la mémoire. Une alternative est d'utiliser encore le chargement différé et ouvrir une session Hibernate chaque fois que vous devez travailler sur la collection, j'.e, chaque fois que vous besoin d'invoquer getRoleSet méthode. De cette façon, Hibernate va exécuter la requête select de base de données à chaque fois que cette méthode est invoquée et n'empêche pas la collecte de données en mémoire. Vous pouvez vous référer à mon post ici pour les détails: http://khuevu.github.io/2013/01/20/understand-hibernate.html
Ce qui est dit, cela peut dépendre de votre utilisation réelle de cas. Si votre collecte de données est petit et vous avez souvent besoin d'interroger les données, vous feriez mieux d'utiliser le chargement agressif. Je pense que, dans votre cas particulier, une collection de rôle est probablement assez petit et adapté à l'utilisation chargement agressif.
Vous pouvez essayer d'ajouter @Transactional annotation à votre haricot ou de la méthode (si la déclaration de toutes les variables endroits dans la méthode).
Vous êtes le plus susceptible de clôture de la session à l'intérieur de la RoleDao. Si vous fermez la session, puis essayez d'accéder à un champ d'un objet qui a été chargement paresseux, vous obtiendrez cette exception. Vous devriez probablement ouvrir et de fermer la session/transaction dans votre test.
J'étais rencontrent le même problème donc juste ajouté le @Transactional d'annotation à partir d'où j'étais l'appel de la méthode DAO. Il fonctionne, tout simplement. Je pense que le problème a été Hibernate ne permet pas de récupérer des sous-objets de la base de données à moins d'être spécifiquement tous les objets nécessaires au moment de l'appel.
Le code suivant peut causer une erreur semblable:
Vous pouvez résoudre le problème simplement:
pour moi, il a travaillé à l'approche que j'ai utilisée dans eclipselink ainsi. Il suffit d'appeler la taille() de la collection qui doit être chargé avant de l'utiliser comme paramètre de pages.
Ici entityListKeeper dispose d'une Liste de l'Entité qui dispose d'une liste de LazyLoadedEntity.
Si vous avez juste therelation Entité dispose d'une liste de LazyLoadedEntity alors la solution est:
Vous avez différents choix pour gérer cela. Il semble comme sa nous ramenant à bon vieux plaine SQL jours 🙂
Lire ceci: http://www.javacodegeeks.com/2012/07/four-solutions-to-lazyinitializationexc_05.html
J'ai eu ce problème en particulier lorsque les entités sont mashalled par Jaxb + Jax-rs. J'ai utilisé la pré-extraction de stratégie, mais j'ai aussi trouvé efficace pour fournir deux entités:
EAGER
Les champs communs et être mappé dans
@MappedSuperclass
et prolongé par deux entité implémentations.Certainement si vous avez toujours besoin de la collections chargée, alors il n'y a pas de raison de ne pas
EAGER
les charger. Dans mon cas, je voulais une version allégée de l'entité pour l'afficher dans une grille.Dans mon cas, l'Exception s'est produite parce que j'avais enlevé le
"mise en veille prolongée.enable_lazy_load_no_trans=true" dans la "mise en veille prolongée."propriétés de fichier...
J'avais fait un copier-coller de la faute de frappe...
Vous essayez de charger le paresseux chargé de la collecte, mais la session hibernate est fermé ou non disponible.
la meilleure solution pour ce problème, modifiez le paresseux objet chargé avides de fetch = FetchType.DÉSIREUX de chargement. ce problème se résoudre.
Vérifier ce blog en espagnol qui vous permet de traduire. Il a aussi quelques références à d'autre documentation.