Hibernate懒惰提取无法加载子对象

问题描述 投票:1回答:3

我有很多子对象的父对象,所以不能使用EAGER。我已经尝试了多种样式来获取父项的所有子对象,但是下面的大小代码,以及我尝试过的所有其他东西抛出

failed to lazily initialize a collection of role xxxx, could not initialize proxy - no Session

如何初始化所有子对象?我真的需要为他们所有人做另一个查询。看起来有点愚蠢。

    @Transactional
    public List<XXX> findYYYinXXX(Long id) {
        List<XXX> list = xxxRepo.findYYY(id);
        for (XXX p : list){
            p.getChild().size();
        }
        return list;
    }

状态,Hibernate.initialize(p.getChild);在for循环中使用也会抛出相同的错误

hibernate spring-boot lazy-loading
3个回答
0
投票

在您的父类中使用提取类型Eager。

1)使用eager fetch类型。

像@OneToMany(fetch = fetchType.Eager)

2)使用join fetch查询。

创建查询时使用获取连接。

例如。 String hql = "select p from ParentClass p join fetch p.child_class_instance;

作为一个侧面提示:在这种情况下使用@ElementCollections至少需要使用@CollectionTable(name =“TABLENAME”,schema =“SCHEMANAME”)


1
投票

如果您使用的是lazy=extra,则在调用sizeisEmpty时不会初始化代理集合。请参阅this answer。你可以得到第一个孩子,而不是调用大小。

但是你的问题没有意义,因为你想要EAGER获取,但你正试图强制加载子。我认为你真正想要的是让这个findYYYinXXX的客户也成为交易的一部分,所以如果它需要加载孩子它就不会失败。


1
投票

如果您使用的是spring-boot,可以在application.properties文件中设置以下属性以保持延迟加载:

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
© www.soinside.com 2019 - 2024. All rights reserved.