当前位置: 首页 > 知识库问答 >
问题:

spring-data-jpa hibernate:未能懒洋洋地初始化集合,无法初始化代理-没有会话

韩嘉祯
2023-03-14

当我试图懒洋洋地读取子实体列表时,我(断断续续地)得到了这个错误。

failed to lazily initialize a collection of role: G.h, could not initialize proxy - no Session

关于这个错误,我已经浏览了一个关于SO的帖子列表。我所能找到的就是执行EAGER fetch或使用hibernate.enable_lazy_load_no_trans属性。我不想做任何一个,因为他们是反模式。

@Service
@Transactional(readOnly = true)
public class AService {

 public void someMethod(Long id) {
        Optional<A> a = ARepository.findById(id); // This is a standard JPA repository interface where I have defined a method findById
        final Optional<G> g = getG(a.get());

        if (g.isPresent()) {
            for (final H h : g.get().getH()) { // Exception is thrown exactly at line ..getH()
               
            }
        }
        
    }

    private Optional<G> getG(final A a) {
        return a.getB()
                .getD()
                .getF()
                .flatMap(F::getG);
    }
}

@Entity
public class A implements Serializable {

    @ManyToOne
    private AGroup aGroup;

    @Transient
    public Optional<B> getB() {
        return getC().map(C::getB);
    }

    public Optional<C> getC() {
        if (aGroup != null) {
            return Optional.ofNullable(aGroup.getC());
        }

        return empty();
    }
}


@Entity
public class AGroup implements Serializable {

    @ManyToOne
    private C c;

    @OneToMany(fetch = EAGER, cascade = ALL, mappedBy = "aGroup")
    private final Set<A> as = new HashSet<>();
}


@Entity
public class C implements Serializable {

    @OneToMany(fetch = LAZY, cascade = ALL, mappedBy = "c")
    private List<AGroup> aGroups = new ArrayList<>();

    @ManyToOne
    private B b;
}

@Entity
public class B implements Serializable {

    @OneToMany(fetch = LAZY, mappedBy = "b")
    private Set<C> cs = new HashSet<>();

    @ManyToOne(fetch = LAZY)
    private D d;
}


@Entity
public class D implements Serializable {

    @OneToMany(fetch = LAZY, mappedBy = "d")
    private final List<B> bs = new ArrayList<>();

    public Optional<F> getF() {
        // based on some other fields return Optional.of(F)
    }
}

@Entity
public class F implements Serializable {

    @ManyToOne
    private G g;

    public Optional<G> getG() {
        return Optional.ofNullable(g);
    }
}

@Entity
public class G implements Serializable {

    @OneToMany(mappedBy = "g")
    private List<F> fs = new ArrayList<>();

    @OneToMany(cascade = ALL, mappedBy = "g")
    private List<H> hs = new ArrayList<>();
}

@Entity
public class H {

    @ManyToOne
    private G g;
}

我使用的是spring-data-jpa。这是一个spring-boot项目。请求来自web层(Rest控制器)

共有1个答案

夏侯华彩
2023-03-14

看起来底层Hibernate会话在某个时候关闭/重新打开,这使得G分离。我不知道arepository.findbyid做什么,也不知道您有什么样的拦截器。

 类似资料: