未能懒惰地初始化角色集合

2022-09-01 13:37:03

嗨,我有两个这样的类:

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);
  • 在另一个事务中获取集合
  • 使用提取配置文件选择惰性/非惰性提取运行时
  • 将抓取设置为非惰性(通常不建议这样做)

此外,我建议您查看右侧的相关链接,其中这个问题之前已经回答过很多次。另请参阅休眠延迟加载应用程序设计


答案 2

您可能没有获取联接集。请务必在 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;

}

推荐