Hibernate initialisation a échoué paresseusement initialiser une collection
J'obtiens l'erreur suivante lorsque j'essaie de récupérer des données de ma table Users, j'ai cherché un web beaucoup, en essayant de découvrir ce qui pourrait être mauvais, mais ne pouvait pas trouver quoi que ce soit, quelqu'un peut-il m'aider en me disant ce que je suis absent /j'ai mal ici?
Erreur:
ERREUR: org.mise en veille prolongée.LazyInitializationException - l'échec de l'paresseusement
initialiser une collection de rôle: com.domaine.crm.domaine.Rôle.les utilisateurs, aucune
session ou la session a été fermée
org.mise en veille prolongée.LazyInitializationException: échec paresseusement initialiser
une collection de rôle: com.domaine.crm.domaine.Rôle.les utilisateurs, pas de session ou
la session a été fermée
Classe d'utilisateur:
@Entity
@Table(name="COM_USER")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="USER_ID")
private Long id;
@Column(name="USER_NAME",nullable=false,length=25,unique=true)
private String userName;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="ROLE_ID",nullable=false)
private Role role;
}
Rôle De La Classe:
@Entity
@Table(name="COM_ROLE")
public class Role {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="ROLE_ID")
private Long id;
@Column(name="ROLE",nullable=false,unique=false)
private Integer Role;
@OneToMany(mappedBy="role")
private Set<User> users=new HashSet<User>();
}
Utilisateur DAO Méthode de classe ne soit invoquée pour recueillir tous les utilisateurs:
public List<User> getUsers(Long page, Long pageSize) {
Long start = (page-1)*pageSize;
return sessionfactory.getCurrentSession().createQuery("from User u ").setFirstResult(start.intValue()).setMaxResults(pageSize.intValue()).list();
}
De Service de l'utilisateur de la méthode de classe:
@Transactional
public List<User> getUsers(Long page, Long pageSize) {
return userdao.getUsers(page, pageSize);
}
Contrôleur de classe de l'appel de la méthode:
@RequestMapping(value = "/users/list-user-data")
@ResponseBody
public UserListData listUserData(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
UserListData listData = new UserListData();
String page = request.getParameter("page");
Long pageLong = Long.parseLong(page);
Long pageSize = (long)15;
List<User> searchResults = iuserservice.getUsers(pageLong, pageSize);
if( searchResults != null ){
List<List<Object>> aaData = new ArrayList<List<Object>>();
List<Object> listItem = null;
for( User u : searchResults ){
listItem = new ArrayList<Object>();
listItem.add(u.getLastName());
listItem.add(u.getFirstName());
listItem.add(u.getUserName());
listItem.add(u.getEmail());
listItem.add(u.getRole());
aaData.add(listItem);
}
listData.setAaData(aaData);
}
int totalCount = iuserservice.getAllUsersCount().intValue();
System.out.println("Number of records in DB: "+totalCount);
listData.setiTotalRecords(totalCount);
return listData;
}
Voici enfin mon pom.xml dépendances:
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.1.0.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.9</org.aspectj-version>
<org.slf4j-version>1.5.10</org.slf4j-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.1.3.RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Commons DBCP -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
</dependencies>
Merci pour votre temps
- L'erreur dit tout. Vous chargez l'objet à partir de la base de données, puis fermer la session. Vous objet est alors dans un état détaché. Puis, vous essayez et de l'accès à une collection en différé. Vous avez besoin d'augmenter la portée de la session - open session in view est un bon modèle. Ou vous pouvez avec impatience charge de la collecte.
- Veuillez prendre un moment pour vérifier que l'Utilisateur de la classe, j'ai déjà avec Impatience charge de la collecte
- Je n'ai pas de fermer la session, de toute façon, l'erreur apparaît alors que je suis dans le milieu de la méthode de contrôleur, avant même de terminer le processus. Merci
- non, vous n'avez pas ardemment charger les utilisateurs. OneToMany associations sont paresseux par défaut. Et oui, la session est fermée dès que la transaction se termine, c'est à dire juste après le transactionnel
UserService.getUsers()
méthode retourne. - Vous devriez faire de votre traitement dans la méthode de service. Et doit retourner
UserListData
à partir de la méthode de service! - Je suis désolé, mais je suis confondu ici, dans la classe d'Utilisateur je suis de chargement les Rôles avec impatience par @ManyToOne(fetch=FetchType.DÉSIREUX), dois-je charger les Utilisateurs désireux de le Rôle de la classe ainsi? Je suis assez confus pour l'instant
- Quand je vais à votre profil, je vois que vous êtes en provenance de Hong Kong. Vous avez donc un ManyToOne association avec Hong Kong. Mais, en voyant votre profil, je ne peux pas connaître tous les utilisateurs de Hong Kong. C'est la même chose ici: vous chargez un utilisateur et que vous connaissez son rôle. Mais cela ne signifie pas que vous savez tous les utilisateurs ayant ce rôle.
- Hmmm, en fonction de votre réponse je suppose que mon problème est plus de entités relation de problème. En d'autres mots, ce que j'ai maintenant c'est que Chaque RÔLE peut avoir de 1 à n UTILISATEURS, puis l'UTILISATEUR de la classe je l'ai chargé avec impatience les RÔLES, bien que basé sur votre réponse, je devrais faire l'inverse, ce qui signifie que je doit avec Impatience charger les Utilisateurs depuis le RÔLE de la classe...j'obtiens ce correct?
- Je ne sais pas ce que vous devriez faire. Tout ce que je dis, c'est que votre code, ou, sans doute, la bibliothèque qui sérialise ce que vous revenez de votre MVC méthode au format XML ou JSON, tente d'accéder à des utilisateurs, des rôles, et que, depuis cette association n'a pas été chargé, il échoue. Vous avez probablement besoin de configurer cette bibliothèque pour ne pas sérialiser non chargé des associations, ou de ne pas essayer de serializee rôles mais de transformer les dans Otd qui "coupe" de l'association.
Vous devez vous connecter pour publier un commentaire.
Je poste l'exemple ici. L'idée de base serait juste d'avoir 3 tables de base de données où les 2 sont des entités
User
etRole
, et la dernière en tant que table de mappage, direuser_role
. Dans la table utilisateur, nous stockons des détails de l'utilisateur, dans le rôle de la table nous stockons rôle de l'id, le nom et la dans notre tableau de correspondance nous avons une carte à l'utilisateur de rôle. Je copie de mon propre projet. Le BaseEntity que mes classes étendre est juste un mappé superclasse générale, pour chaque entité, telle qu'une pièce d'identité, de création/date de modification, etc.Entité utilisateur
Rôle de l'entité
Noter que
ManyToMany
utilise par défaut avec impatience type d'extraction, donc nous n'avons pas besoin de la définir. Maintenant, quand j'aurais une requête pour monUser
entité de mon service. Lerole
ne serait pas obtenir par les cheveux. Si j'ai besoin d'obtenir des rôles qui appartiennent à cet utilisateur alors que je dois manuellement les récupérer avec la requête. J'utilise Spring Data JPA référentiel et de la requête, par exemple, ressembler à ça pour un résultat unique.UserRepository classe
Et puis dans votre
UserService
couche que vous l'utilisiez référentiel/DAO requête. Pour moi, en utilisant le très extraction sur les rôles est nécessaire, parce que chaque fois que je veux requête pour userlist, je n'ai pas n'ont pas besoin d'obtenir le rôle, parce que dans mon projet, les rôles ont également un ensemble d'autorisations et c'est juste pas la peine de requête pour des trucs que vous n'avez pas besoin.Le problème est que
@OneToMany
associations sont paresseux par défaut et par le temps que vous appelezgetUsers()
la session est déjà fermé dans votre méthode de service.Une façon de le résoudre est de ardemment le chargement des enregistrements enfants. Mais être prudent, car cela peut entraîner une charge trop grand nombre de données qui permettra de ralentir et de tuer la mémoire. Par exemple, dans votre
Role
entité, si vous définissez avec impatience chargeUsers
:Chaque fois que vous chargez un
Role
, Hibernate va charger tous ses enfantsUsers
.Une façon de prendre votre cas est de faire tout le travail sur le service intérieur de
@Transactional
méthode qui devrait permettre de session est toujours ouverte(C'est mieux d'avoir des méthodes de service@Transactional
au lieu de DAOs)Quelque part (pas indiqué dans le code ci-dessus) vous accédez à une méthode de la
users
collection de champ dans unRole
entité.Vous ne pouvez pas charger
Roles
collection de la même transaction avec hâte type d'extraction. Pour contourner ce problème, vous devez initialiser manuellement les Rôles de collecte ou de fairefetch join
sur votre requête. Cela devrait résoudre le problème pour vous.Aussi je vous recommande d'avoir
ManyToMany
relation entreUser
etRoles
et l'utilisation de la table de correspondance. Utiliser le ci-dessous et supprimer des utilisateurs jeu de rôle de l'entité. Il est inutile de dupliquer le rôle des enregistrements sur le tableau des rôles.searchResults
liste.