当前位置: 首页 > 面试题库 >

在Spring JSP页面中使用集合时,休眠LazyInitializationException

宰坚
2023-03-14
问题内容

我有这样的实体:

@Entity
@Table(name = "ASSESSMENT")
public class Assessment {

    //All other fields..

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "assessment")
    @OrderBy(value = "order ASC")
    private List<AssessmentPart> assessmentParts = new LinkedList<>();

    public List<AssessmentPart> getAssessmentParts() {
        return assessmentParts;
    }

    //All other getters/setters
}

另一个:

@Entity
@Table(name = "ASSESSMENT_PART")
public class AssessmentPart {

    //All other fields

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ASSESSMENT_ID", nullable = false)
    private Assessment assessment;

    public Assessment getAssessment() {
        return assessment;
    }

    public void setAssessment(Assessment assessment) {
        this.assessment = assessment;
    }

    //All other getters/setters
}

评估部件是从评估实体延迟加载的。我也有弹簧控制器方法,它是数据库的事务和负载评估部分:

@Transactional
public void doSomething(String partId, Map<String, Object> model) {

    AssessmentPart assessmentPart = //laods a part with entity manager
    Assessment assessment = assessmentPart.getAssessment(); //Getting the assessments

    model.put("assessmentParts", assessment.getAssessmentParts()); //adding all assessments parts into spring model map
}

将评估部分添加到Spring模型图后,它们将在我的JSP页面中可用,并且我正在使用JSTL遍历它们:

<c:forEach var="assessmentPart" items="${assessmentParts}">
     //Not loading any lazy stuff, just getting an ID of assessment part
</c:forEach>

此JSP页面抛出异常:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: my.package.something.Assessment.assessmentParts, could not initialize proxy - no Session

如果此集合已在事务中加载,怎么办?我只是试图遍历,hibernate状态此时不应该加载任何东西,因为它已经被加载了。为什么发生这种奇怪的事情?


问题答案:

在视图中,entitymanager已关闭,因此集合中的元素无法在其中检索属性。您在控制器中编写的代码不会初始化集合中的元素(这是一个LAZY集合),而只会初始化集合(而不是其中的元素)。

通过OpenEntityManagerInViewFilter在您的Web配置中配置,可以强制entitymanager保持打开状态。

或更改您的控制器代码以包含一个调用Hibernate.initialize以正确初始化您的集合。

@Transactional
public void doSomething(String partId, Map<String, Object> model) {

    AssessmentPart assessmentPart = //laods a part with entity manager
    Assessment assessment = assessmentPart.getAssessment(); //Getting the assessments
    Hibernate.initialize(assesment.getAssesmentParts()); // Init collection
    model.put("assessmentParts", assessment.getAssessmentParts()); //adding all assessments parts into spring model map
}

要么创建一个自定义查询,以强制获取集合。



 类似资料:
  • 问题内容: 在具有两种类型的实体(父级和子级)的场景中: 父母-@OneToMany Collection孩子; 默认设置是对子级集合进行延迟加载。这种模式对少数儿童非常有效,但是如果这个数字很大,这似乎是不可持续的。因此,在某些情况下,我认为孩子的数量会很大,因此我使用了分页的服务方法(例如“ getChildren(父父母,int偏移量,int计数)”)。 问题是:这是处理此类情况的最佳方法吗

  • 问题内容: 我想问一下是否有可能使用hibernate方式做到这一点。假设我已经运行了HQL并检索了一个集合。是否可以使用hibernate进一步过滤它? 我试图在标头类中使用,并在查询之前添加session.enable(),但似乎无法正常工作。 样例代码 精简HQL 问题答案: 不。至少不是您问的方式。一旦您要求Hibernate(使用方法)访问数据库,Hibernate就发挥了作用,结果现在

  • 问题内容: 我正在测试休眠并将此查询提供给 我在命令行中得到这些查询: 我使用的是“合并不保存”,所以为什么休眠要更新我的对象,所以不应该更新。对吗 怎么了 问题答案: 我将尝试使用一个更具体的示例进行解释。假设您有以下情况: 尝试重新附加分离的对象时发生异常,userA。 为了解决上述问题,使用了merge(),如下所示:

  • 问题内容: 我正在浏览hibernate文档,并遇到了逆属性的概念。我是Hibernate的新手,所以我很难正确理解该概念。 http://docs.jboss.org/hibernate/orm/3.3/reference/zh- CN/html/collections.html#collections- bidirectional 从上面的代码中,应用于类别,因此我知道类别是相反的一端。 但是

  • 问题内容: 细节 来自应用程序的HQL查询: 查询返回300万条记录,而对于分页,我们仅设置了其中的50条记录,分页页面的运行速度非常慢,因为每次刷新时,我们都调用查询来获取300万条记录,而其中只有50条记录。 我的主要问题是 HQL是始终运行并命中数据库还是运行命中会话或内存以查找数据,如果它每次都运行时命中数据库并获取结果集,那么从性能的角度来看,这是非常合适的,什么是改进的最佳解决方案它?

  • 问题内容: 我一直遇到这个问题: 我想让休眠管理一个表,该表代表一个集合的集合。例如: 地图地图 套装清单 清单地图 例如,我希望能够代表这一点: 作为一个表: 没有自定义的休眠代码似乎是不可能的,我不介意。但是我希望有人对自定义代码的外观有所指导。 我应该扩展AbstractPersistentCollection吗? CompositeUserType? 可以管理多个表是否正常,但是从数据库角