懒惰地初始化角色集合失败
Posted
技术标签:
【中文标题】懒惰地初始化角色集合失败【英文标题】:failed to lazily initialize a collection of role 【发布时间】:2011-07-21 05:57:43 【问题描述】:您好,我有两个这样的课程:
public class Indicator implements Serializable
...
@OneToMany(mappedBy = "indicator",fetch=FetchType.LAZY)
private List<IndicatorAlternateLabel> indicatorAlternateLabels;
public List<IndicatorAlternateLabel> getIndicatorAlternateLabels()
return indicatorAlternateLabels;
public void setIndicatorAlternateLabels(List<IndicatorAlternateLabel> indicatorAlternateLabels)
this.indicatorAlternateLabels = indicatorAlternateLabels;
...
public class IndicatorAlternateLabel implements Serializable
...
@ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
@JoinColumn(name = "IndicatorID")
@XmlTransient
private Indicator indicator;
...
当我这样使用它们时:
public MetricTypeDetail getMetricTypeDetail(Integer metricTypeId)
Criteria crit = sessionFactory.getCurrentSession().createCriteria(Indicator.class, "sub")
.add(Restrictions.eq("number", metricTypeId))
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).setCacheable(true);
crit.setMaxResults(1);
Indicator indicator=(Indicator) crit.uniqueResult();
MetricTypeDetail metricTypeDetail=new MetricTypeDetail(indicator);
List<IndicatorAlternateLabel> indicatorAlternateLabels = null;
indicatorAlternateLabels=indicator.getIndicatorAlternateLabels();
metricTypeDetail.setIndicatorAlternateLabels(indicatorAlternateLabels);
return metricTypeDetail;
此代码返回异常: 未能延迟初始化角色集合:com.porism.service.domain.Indicator.indicatorAlternateLabels,没有会话或会话已关闭
有什么想法吗?我对 Hibernate 很陌生
【问题讨论】:
【参考方案1】:当您获取通常包含延迟加载的集合的对象并尝试访问该集合时,会发生延迟异常。
你可以通过
避免这个问题 访问事务中的惰性集合。 使用Hibernate.initialize(obj);
初始化集合
在另一个事务中获取集合
使用Fetch profiles
选择惰性/非惰性获取运行时
将 fetch 设置为 non-lazy(一般不推荐)
此外,我建议您查看右侧的 related
链接,该问题之前已多次回答。另见Hibernate lazy-load application design。
【讨论】:
Fetching 意味着使用 JPQL 进行查询,我认为仅使用事务通过集合检索关联是行不通的【参考方案2】:您可能没有获取 Joined Set。请务必在您的 HQL 中包含该集合:
public List<Node> getAll()
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("FROM Node as n LEFT JOIN FETCH n.nodeValues LEFT JOIN FETCH n.nodeStats");
return query.list();
您的班级有 2 套,例如:
public class Node implements Serializable
@OneToMany(fetch=FetchType.LAZY)
private Set<NodeValue> nodeValues;
@OneToMany(fetch=FetchType.LAZY)
private Set<NodeStat> nodeStats;
【讨论】:
【参考方案3】:尝试将 fetchType 从 LAZY 切换为 EAGER
...
@OneToMany(fetch=FetchType.EAGER)
private Set<NodeValue> nodeValues;
...
但在这种情况下,您的应用无论如何都会从数据库中获取数据。 如果此查询非常困难 - 这可能会影响性能。 更多在这里: https://docs.oracle.com/javaee/6/api/javax/persistence/FetchType.html
==> 73
【讨论】:
【参考方案4】:建议here解决著名的LazyInitializationException是以下方法之一:
(1) 使用 Hibernate.initialize
Hibernate.initialize(topics.getComments());
(2) 使用 JOIN FETCH
您可以在 JPQL 中使用 JOIN FETCH 语法来显式提取子集合。这有点像 EAGER 抓取。
(3) 使用 OpenSessionInViewFilter
LazyInitializationException 经常发生在视图层。如果你使用 Spring 框架,你可以使用 OpenSessionInViewFilter。但是,我不建议您这样做。如果使用不当,可能会导致性能问题。
【讨论】:
以上是关于懒惰地初始化角色集合失败的主要内容,如果未能解决你的问题,请参考以下文章
懒惰初始化角色集合失败:someEnttiy.otherTitles
org.hibernate.LazyInitializationException:懒惰初始化角色集合失败(Hibernate + Spring)
Hibernate 无法懒惰地初始化角色集合 无法初始化代理 - 没有会话
无法懒惰地初始化角色集合,..无法初始化代理 - 无会话 - JPA + SPRING
Spring Boot 中的 Hibernate 无法懒惰地初始化角色集合,无法初始化代理 - 没有 Session 异常