繁体   English   中英

Vaadin Spring 和 Hibernate:无法初始化代理 - 否 Session

[英]Vaadin Spring and Hibernate: could not initialize proxy - no Session

Model:

    @Entity
    ...
    public class ScolProgressionPopulation {    
       ...        
        @OneToMany(mappedBy = "population")
        private List<ScolProgressionSemestre> progressions;        
       ...
    }

回购:

    public interface ScolProgressionPopulationRepository extends JpaRepository<ScolProgressionPopulation, Long>

风景:

    @Route(value = "progression", layout = ApplicationLayout.class)
    @RouteAlias(value = "", layout = ApplicationLayout.class)
    public class ProgressionView extends Div {
           public ProgressionView(@Autowired ScolProgressionPopulationRepository scolProgressionPopulationRepository) {
               var items = scolProgressionPopulationRepository.findAll();

               // I try this..
               Hibernate.initialize(items);
               // and this ...
               Hibernate.initialize(items.get(0));

               // this works:
               System.out.println("this is ok:" +items.size());

               // but not this:
               System.out.println("err, could not initialize proxy - no Session :" +items.get(0).getProgressions().size());

我尝试了很多方法来使延迟加载工作,(添加@Transactional,Hibernate.initialize ...)

但我总是以这个错误结束:

org.springframework.beans.factory.BeanCreationException:创建名为“nc.unc.scolarite.lmd.progression.gui.ProgressionView”的 bean 时出错:通过构造函数实例化 Bean 失败; 嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 [nc.unc.scolarite.lmd.progression.gui.ProgressionView]:构造函数抛出异常; 嵌套异常是 org.hibernate.LazyInitializationException:无法延迟初始化角色集合:nc.unc.scolarite.lmd.progression.entities.ScolProgressionPopulation.progressions,无法初始化代理 - 否 Session

PS:我不想使用EAGER fetch。 我想延迟加载数据。

您可以在您的存储库中创建一个新方法,该方法使用join fetch来获取相关实体,例如

@Query("SELECT spp FROM ScolProgressionPopulation spp JOIN FETCH spp.progressions")
public List<ScolProgressionPopulation> findAllWithProgressions();

另一种方法是将@Transactional注释添加到存储库中的方法(那么它不能是接口),它也可能适用于您视图中的方法。 您可能需要为所有进程 collections 调用initialize ,这不是很有效,因为它可能会创建许多数据库查询。

@Transactional
public List<ScrolProgressionPopulation> findAllWithProgressions() {
    val spps = findAll();
    for(ScrolProgressionPopulation spp: spps) {
        Hibernate.initialize(spp.getProgressions();
    }
    return spps;
}

编辑:如果你不想初始化所有项目,你可以做这样的事情

@Transactional
public void initializeProgressions(ScrolProgressionPopulation spp) {
    Hibernate.initialize(spp.getProgressions());
}

并按需调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM