Не удалось лениво инициализировать коллекцию роли
Привет, у меня есть два класса:
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 на не-ленивый (что обычно не рекомендуется)
Далее я бы рекомендовал посмотреть ссылки related
справа, где этот вопрос был дан много раз. Также см. Hibernate lazy-load application design.
Ответ 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;
}
Ответ 3
Попробуйте swich fetchType от LAZY до EAGER
...
@OneToMany(fetch=FetchType.EAGER)
private Set<NodeValue> nodeValues;
...
Но в этом случае ваше приложение будет извлекать данные из БД в любом случае.
Если этот запрос очень сложно - это может повлиять на производительность.
Подробнее здесь:
https://docs.oracle.com/javaee/6/api/javax/persistence/FetchType.html
== > 73