【问题标题】:could not initialize proxy - no Session (Spring-Hibernate-one to one)无法初始化代理 - 没有会话(Spring-Hibernate-一对一)
【发布时间】:2015-10-09 10:10:51
【问题描述】:

我有两个表,我想从数据库中获取更新数据。
用户表(列):

user_id - username - password - role_id(Foreign Key) - email

user_roles 表(列):

role_id - role

我想在 users.jsp 中列出用户。让我们看看我的代码:
用户.java

package com.terafast.manager.model;

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private Role role;

    public User() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

角色.java

package com.terafast.manager.model;

public class Role {
    private int id;
    private String role;

    public Role() {

    }

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

    public long getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

用户.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.terafast.manager.model">
    <class name="User" table="users">
        <id name="id" column="USER_ID">
            <generator class="native" />
        </id>
        <property name="username" column="USERNAME" />
        <property name="password" column="PASSWORD" />
        <property name="email" column="EMAIL" />

        <many-to-one name="Role" class="com.terafast.manager.model.Role"
            unique="true" not-null="true" column="role_id" />
    </class>
</hibernate-mapping>

角色.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.terafast.manager.model">
    <class name="Role" table="user_roles">
        <id name="id" column="role_id">
            <generator class="native" />
        </id>
        <property name="role" />
    </class>
</hibernate-mapping>

这部分来自创建用户列表的 UserDAOImpl:

@Override
@Transactional
public List<User> list() {
    @SuppressWarnings("unchecked")
    List<User> listUser = (List<User>) sessionFactory.getCurrentSession().createCriteria(User.class)
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

    return listUser;
}

我已经声明了 public List list();在 UserDAO 界面中。 这是我从控制器向 users.jsp 发送用户列表的部分:

@RequestMapping("/users/show")
public ModelAndView handleRequest() throws Exception {
    List<User> listUsers = userDao.list();
    ModelAndView model = new ModelAndView("panel/users");
    model.addObject("userList", listUsers);
    return model;
}

在 jsp 文件中,我列出了这样的用户:

<c:forEach var="user" items="${userList}" varStatus="status">
    <tr>
        <td>${status.index + 1}</td>
        <td>${user.username}</td>
        <td>${user.email}</td>
        <td>${user.role}</td>
        <td><a href="edit?id=${user.id}">Edit</a>
            &nbsp;&nbsp;&nbsp;&nbsp; <a href="delete?id=${user.id}">Delete</a>
        </td>
    </tr>
</c:forEach>

所以当我将这个项目作为服务器运行时,我得到了这个输出:

Hibernate: select this_.USER_ID as USER_ID1_1_0_, this_.USERNAME as USERNAME2_1_0_, this_.PASSWORD as PASSWORD3_1_0_, this_.EMAIL as EMAIL4_1_0_, this_.role_id as role_id5_1_0_ from users this_

然后这个错误:

Jul 20, 2015 3:32:06 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
org.hibernate.LazyInitializationException: could not initialize proxy - no Session

有人能解释一下我的程序有什么问题吗?如果我想添加或编辑用户,我应该怎么做?

【问题讨论】:

    标签: java spring hibernate spring-mvc


    【解决方案1】:

    默认情况下,Hibernate 中的所有关联都是惰性的(与默认情况下需要一对一关联的 JPA 不同)。

    要么在UserRole 之间建立关联(lazy="false"):

    <many-to-one name="Role" class="com.terafast.manager.model.Role"
       lazy="false" unique="true" not-null="true" column="role_id" />
    

    或显式初始化您打算在会话边界之外使用的惰性关联:

    @SuppressWarnings("unchecked")
    List<User> listUser = (List<User>) sessionFactory.getCurrentSession().createCriteria(User.class)
       .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
    
    for (User user : listUser) {
       Hibernate.initialize(user.getRole());
    }
    

    那么在 users.jsp 中,你应该使用${user.role.role} 来访问该值。

    【讨论】:

    • 你能解释一下Hibernate中的懒惰吗?
    • 在 Hibernate 中延迟 意味着如果您不使用 JPA 注释,而是在 Hibernate xml 中定义映射(就像您的情况一样),那么默认情况下所有关联都是惰性的。
    • 懒惰是什么意思?
    • Here 是一个很好且简短的解释。有关更多详细信息,您必须阅读 Hibernate 教程;它不能全部放在答案或评论中。
    • 我的第二个问题有教程吗?
    【解决方案2】:

    您的异常完全取决于延迟加载和急切加载。 在 user.hbm.xml 文件中使用 false 设置 &lt;many-to-one&gt; 与惰性属性的关系。

    试试这个:

    <many-to-one name="Role" class="com.terafast.manager.model.Role"
       lazy="false" fetch="select" unique="true" not-null="true" column="role_id" />
    

    并关注@Dragan Bozanovic 的回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2012-11-09
      • 2010-11-15
      • 1970-01-01
      • 2021-03-13
      • 2013-05-22
      • 1970-01-01
      相关资源
      最近更新 更多