spring-data jpa-hibernate:未能延迟初始化集合,无法初始化proxy-no-Session



当我试图懒洋洋地读取子实体列表时,我(间歇性地(收到了这个错误。

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

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

我在类级别上确实有@Tranastional(readOnly=true),我正在从数据库中读取数据,所以我希望hibernate会话在事务完成之前一直处于打开状态。

此外,这个错误只会偶尔出现一次。大多数时候根本没有问题。还有一件事是,我可以确认实体是延迟加载的(除了明确指定EAGER的地方(,因为我可以看到sql语句被记录,当实体被读取时。

下面是我的代码在坚果壳中的样子。

@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;
}

任何人都知道是什么导致了这个问题(更重要的是,为什么这种情况会间歇性发生(

我使用的是春季数据jpa。这是一个春季启动项目。请求来自web层(Rest Controller(

看起来底层Hibernate会话在某个时刻被关闭/重新打开,从而使G分离。我不知道ARepository.findById做什么,也不知道你有什么类型的拦截器。

最新更新