Java 延迟加载在需要时不检索

Java 延迟加载在需要时不检索,java,spring,hibernate,Java,Spring,Hibernate,我有一个以这种方式引用部门的用户bean: @Column(name = "DEPARTMENT_ID", length = 2) public String getDepartmentId() { return this.departmentId; } public void setDepartmentId(String departmentId) { this.departmentId = departmentId; } @ManyToOne(fetch = FetchT

我有一个以这种方式引用部门的用户bean:

@Column(name = "DEPARTMENT_ID", length = 2)
public String getDepartmentId() {
    return this.departmentId;
}

public void setDepartmentId(String departmentId) {
    this.departmentId = departmentId;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPARTMENT_ID", nullable = false, insertable=false, updatable=false)
public Department getDepartment() {
    return this.department;
}

public void setDepartment(Department department) {
    this.department = department;
}
。。在部门里

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "department")
public List<User> getUsers() {
    return users;
}

public void setUsers(List<User> users) {
    this.users = users;
}
我明白了:

org.hibernate.LazyInitializationException:无法初始化代理 -没有会议

这是userService.getUser():

。。和userDAO.findById():

我还应该提到,我正在使用OpenSessionInViewFilter:

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>sessionFactory</param-value>
    </init-param>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>

冬眠过滤器
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
sessionFactoryBeanName
会话工厂
单一会话
假的
有人能告诉我为什么LazyInitialization例外吗

谢谢


顺便说一句,我使用的是Hibernate 3.6.10和Spring 3.2.4,请尝试在配置中将singleSession参数更改为true,然后看看这种情况,此时您没有打开的会话,因此代码无法访问数据库

我猜您的UserService上有一个事务(通常您将它放在服务层上),并且由于您正在访问服务层之外的lazy属性,因此您的事务和会话将关闭。默认情况下,会话绑定到事务

要么:

  • 将此代码也放在会话中
  • 在离开事务之前,确保填充了所有必填字段
  • 使此代码具有事务性(在内部事务上传播)
  • 使用OpenSessionInView(警告:这里有龙)

连接了OpenSessionInViewFilter源代码,并在getSession()和closeSession()方法中设置了一些停止符,很明显它没有被使用。进一步的搜索表明web.xml中过滤器映射的顺序在这方面非常重要将OpenSessionInViewFilter的筛选器映射移动到my servlet筛选器之前的筛选器映射解决了问题。


感谢所有回复者。

您的会话工厂在异常发生之前会被调用吗?为什么
singleSession
设置为
false
?它已经看过了可能的感谢复制件。我已将singleSession参数更改为true,但仍然遇到相同的问题。不确定您指的是懒惰初始化问题的哪一部分-它似乎不太相似我的UserService上确实有一个事务,但我使用的是OpenSessionInView,它总体上运行良好。我可以在我的Faces页面上引用尚未加载的bean,通常不会出现问题,但偶尔我会遇到这样的问题,因为它不起作用。我想我想弄清楚的是,为什么在这个特定的案例中,OpenSessionInView 99%的时间都在工作。也许是我访问服务的方式?也许你在某个地方关闭了会话?使用调试器检查您正在检索的userservice是真正的bean还是事务代理(后者是您想要的)。然后检查当前会话在方法内部和外部是否相同(因为您使用的是OSIV,您希望它相同),确定它是代理。我如何获得要检查的方法内外会话的句柄?@NeilRichards您需要将sessionfactory注入到调用bean中。然后在调用bean和服务中放置断点。然后在sessionFactory.getCurrentSession()上添加一个监视。内存位置应该相同。如果这没用,你就得追踪到hibernate。有时我们都必须去那里:)但是在这里发布解决方案。“调用bean”实际上是一个servlet过滤器,所以不能注入。但是,如果我使用SpringApplicationContext.getBean()来获取sessionfactory,我可以很好地获得它,但是getCurrentSession()抛出一个HibernateException:当前没有绑定到执行上下文的会话。如果没有OpenSessionInViewFilter,我想这是可以理解的,但确实有
public User getUser(String userId) throws ApplicationException {

    User user = null;
    try {
        user = userDAO.findById(userId);
    }
    catch(Exception e) {
        ApplicationException.handleThrowable(e, userId, this.getClass());
    }
    return user;
}
public User findById(String id) {

    return ( User )getSession().get( User.class, id );
}
<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>sessionFactory</param-value>
    </init-param>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>