Hibernate懒惰初始化 - 未能懒惰地初始化集合 [英] Hibernate lazy initialization - failed to lazily initialize a collection

查看:99
本文介绍了Hibernate懒惰初始化 - 未能懒惰地初始化集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我尝试从我的用户表中检索数据时,我都会收到以下错误,我在网上搜索了很多内容,试图找出哪些内容可能是错误的,但找不到任何内容,因此有人可以通过告诉我我缺少什么/我在这里有错误?



错误:


错误:org.hibernate.LazyInitializationException - 无法延迟
初始化角色集合:com.domain.crm.domain.Role.users,no
会话或会话已关闭
org.hibernate .LazyInitializationException:未能延迟初始化
a角色集合:com.domain.crm.domain.Role.users,没有会话或
会话已关闭


User class:

  @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;
$ b @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name =ROLE_ID,nullable = false)
私人角色角色;



$ b $ p $角色类:



$ b

  @Entity 
@Table(name =COM_ROLE)
public class Role {
@Id
@GeneratedValue(strategy = GenerationType .AUTO)
@Column(name =ROLE_ID)
私人长ID;

@Column(name =ROLE,nullable = false,unique = false)
私人整数角色;

@OneToMany(mappedBy =role)
private Set< User> users = new HashSet< User>();

用户DAO类方法被调用来收集所有用户:

  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();

用户服务类方法:

  @Transactional 
public List< User> getUsers(Long page,Long pageSize){
返回userdao.getUsers(page,pageSize);

调用方法的控制器类:

  @RequestMapping(value =/ users / list-user-data)
@ResponseBody
public UserListData listUserData(HttpServletRequest请求,HttpServletResponse响应,模型模型)抛出异常{

UserListData listData = new UserListData();

String page = request.getParameter(page);
Long pageLong = Long.parseLong(page);
Long pageSize =(long)15;

列表<用户> searchResults = iuserservice.getUsers(pageLong,pageSize);

if(searchResults!= null){
List< List< Object>> aaData = new ArrayList< List< Object>>();
列表< 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(DB中的记录数:+ totalCount);
listData.setiTotalRecords(totalCount);

return listData;
}

最后这里是我的pom.xml依赖项:

 <属性> 
< 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>

<依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-context< / artifactId>
< version> $ {org.springframework-version}< / version>
<排除项>
<! - 排除Commons记录SLF4j - >
<排除>
< groupId> commons-logging< / groupId>
< artifactId> commons-logging< / artifactId>
< /排除>
< /排除>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-webmvc< / artifactId>
< version> $ {org.springframework-version}< / version>
< /依赖关系>
<! - AspectJ - >
< dependency>
< groupId> org.aspectj< / groupId>
< artifactId> aspectjrt< / artifactId>
< version> $ {org.aspectj-version}< / version>
< /依赖关系>
<! - 记录 - >
< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> slf4j-api< / artifactId>
< version> $ {org.slf4j-version}< / version>
< /依赖关系>
< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> jcl-over-slf4j< / artifactId>
< version> $ {org.slf4j-version}< / version>
< scope>运行时< / scope>
< /依赖关系>
< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> slf4j-log4j12< / artifactId>
< version> $ {org.slf4j-version}< / version>
< scope>运行时< / scope>
< /依赖关系>
< dependency>
< groupId> log4j< / groupId>
< artifactId> log4j< / artifactId>
< version> 1.2.15< / version>
<排除项>
<排除>
< groupId> javax.mail< / groupId>
< artifactId>邮件< / artifactId>
< /排除>
<排除>
< groupId> javax.jms< / groupId>
< artifactId> jms< / artifactId>
< /排除>
<排除>
< groupId> com.sun.jdmk< / groupId>
< artifactId> jmxtools< / artifactId>
< /排除>
<排除>
< groupId> com.sun.jmx< / groupId>
< artifactId> jmxri< / artifactId>
< /排除>
< /排除>
< scope>运行时< / scope>
< /依赖关系>

<! - @Inject - >
< dependency>
< groupId> javax.inject< / groupId>
< artifactId> javax.inject< / artifactId>
< version> 1< / version>
< /依赖关系>

<! - Servlet - >
< dependency>
< groupId> javax.servlet< / groupId>
< artifactId> servlet-api< / artifactId>
< version> 2.5< / version>
< scope>提供< / scope>
< /依赖关系>
< dependency>
< groupId> javax.servlet.jsp< / groupId>
< artifactId> jsp-api< / artifactId>
< version> 2.1< / version>
< scope>提供< / scope>
< /依赖关系>
< dependency>
< groupId> javax.servlet< / groupId>
< artifactId> jstl< / artifactId>
< version> 1.2< / version>
< /依赖关系>
<! - Test - >
< dependency>
< groupId> junit< / groupId>
< artifactId> junit< / artifactId>
< version> 4.7< / version>
< scope> test< / scope>
< /依赖关系>
<! - Spring Security - >
< dependency>
< groupId> org.springframework.security< / groupId>
< artifactId> spring-security-core< / artifactId>
< version> 3.1.3.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework.security< / groupId>
< artifactId> spring-security-web< / artifactId>
< version> 3.1.3.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework.security< / groupId>
< artifactId> spring-security-config< / artifactId>
< version> 3.1.3.RELEASE< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework.security< / groupId>
< artifactId> spring-security-taglibs< / artifactId>
< version> 3.1.3.RELEASE< / version>
< type> jar< / type>
< scope>编译< / scope>
< /依赖关系>
<! - Mysql - >
< dependency>
< groupId> mysql< / groupId>
< artifactId> mysql-connector-java< / artifactId>
< version> 5.1.6< / version>
< /依赖关系>
<! - Hibernate - >
< dependency>
< groupId> org.hibernate< / groupId>
< artifactId> hibernate-entitymanager< / artifactId>
< version> 3.6.0.Final< / version>
< /依赖关系>
< dependency>
< groupId> org.springframework< / groupId>
< artifactId> spring-orm< / artifactId>
< version> $ {org.springframework-version}< / version>
< /依赖关系>
<! - Commons DBCP - >
< dependency>
< groupId> commons-dbcp< / groupId>
< artifactId> commons-dbcp< / artifactId>
< version> 1.2.2< / version>
< /依赖关系>
< dependency>
< groupId> org.apache.maven.plugins< / groupId>
< artifactId> maven-resources-plugin< / artifactId>
< version> 2.4.3< / version>
< /依赖关系>
< dependency>
< groupId> net.sf.jasperreports< / groupId>
< artifactId> jasperreports< / artifactId>
< version> 5.2.0< / version>
< /依赖关系>
< dependency>
< groupId> commons-collections< / groupId>
< artifactId> commons-collections< / artifactId>
< version> 3.1< / version>
< /依赖关系>
< /依赖关系>

感谢您的宝贵时间

解决方案

我在这里发布示例。基本思想是只有3个数据库表,其中2个用于实体用户角色,最后一个为映射表,例如 user_role 。在用户表中,我们存储用户详细信息,在角色表中存储角色ID和名称,并在我们的映射表中将用户映射到角色。我从我自己的项目中复制。我的类扩展的BaseEntity只是一个映射的超类,它具有用于每个实体的一般字段,例如id,创建/修改日期等。

用户实体

  @Entity 
@Table(name =user_t)
public class用户扩展BaseEntity {

@Column(name =username,nullable = false,unique = true)
private String userName;

@Column(name =password,nullable = false)
private String password;
$ b @ManyToMany
@JoinTable(name =user_role,joinColumns = @JoinColumn(name =user_id),inverseJoinColumns = @JoinColumn(name =role_id))
私人设置<角色> role = new HashSet< Role>();

// getters&




$ b

角色实体



  @Entity(name =role_t)
public class Role扩展BaseEntity {

@Column(name =role_name,nullable = false )
private String roleName;
$ b $ public Role(){
}

public Role(String roleName){
this.roleName = roleName;
}

// getters& setters
}

请注意 ManyToMany 默认情况下使用热切获取类型,所以我们不需要设置它。现在,当我从我的服务中查询我的 User 实体时。 角色集合不会被获取。如果我需要获取属于该用户的角色,那么我需要用查询手动获取它们。我使用Spring Data JPA存储库,查询例如看起来就像是单个结果。



UserRepository class

  public interface UserRepository扩展JpaRepository< User,Long> {

@Query(SELECT u FROM User u JOIN FETCH u.role WHERE u.userName =(:userName))
public User findByUserNameAndFetchRoles(@Param(userName)String用户名);

@Query(FROM用户u JOIN FETCH u.role)
public List< User> getAllUsersAndFetchRoles(); // **查询你会使用!**
}

然后在你的 UserService 层将使用该存储库/ DAO查询。对我来说,使用角色上的热切获取是必要的,因为每次我想查询用户列表时,我都不需要获取角色,因为在我的真实项目中角色也具有一组权限,这是不值得去查询你不需要的东西。


I am getting the following error whenever I try to retrieve data from my Users table, I've searched a web a lot trying to find out what could be wrong but couldn't find anything so can someone please help me by telling me what I am missing / I have wrong here?

Error:

ERROR: org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.domain.crm.domain.Role.users, no session or session was closed org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.domain.crm.domain.Role.users, no session or session was closed

User class:

@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;
}

Role Class:

@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>();
}   

User DAO class Method being invoked to collect all users:

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();
}

User Service class method:

@Transactional
public List<User> getUsers(Long page, Long pageSize) {
    return userdao.getUsers(page, pageSize);
}

Controller class calling the method:

@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;
}

Finally here is my pom.xml dependencies:

<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>

Thanks for your time

解决方案

I post the example here. The basic idea would be just to have 3 database tables where 2 are for entities User and Role, and last one as mapping table, say user_role. In user table we store user details, in role table we store role id and name and in our mapping table we map the user to role. I copy from my one own project. The BaseEntity that my classes extend is just a mapped superclass that has general fields for every entity such as id, created/modified date etc.

User entity

@Entity
@Table(name = "user_t")
public class User extends BaseEntity {

    @Column(name = "username", nullable = false, unique = true)
    private String userName;

    @Column(name = "password", nullable = false)
    private String password;

    @ManyToMany
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> role = new HashSet<Role>();

    // getters & setters
}

Role entity

@Entity(name = "role_t")
public class Role extends BaseEntity {

    @Column(name = "role_name", nullable = false)
    private String roleName;

    public Role() {
    }

    public Role(String roleName) {
        this.roleName = roleName;
    }

    // getters & setters
}

Note that ManyToMany by default uses eagerly fetch type so we don't need to set it. Now when I would query for my User entity from my service. The role collection would not get fetched. If I need to get roles that belong to that user then I need to manually fetch them with the query. I use Spring Data JPA repository and the query for example would look like that for a single result.

UserRepository class

public interface UserRepository extends JpaRepository<User, Long> {

    @Query("SELECT u FROM User u JOIN FETCH u.role WHERE u.userName = (:userName)")
    public User findByUserNameAndFetchRoles(@Param("userName") String userName);

    @Query("FROM User u JOIN FETCH u.role")
    public List<User> getAllUsersAndFetchRoles(); // **query that you would use!**
}

And then in your UserService layer you would use that repository/DAO query. For me using the eagerly fetch on the roles is necessary, because every time I would want to query for userlist, I don't don't need to get the roles, because in my real project the roles also have a set of permissions and it's just not worth to query for stuff you don't need.

这篇关于Hibernate懒惰初始化 - 未能懒惰地初始化集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆