Ответ 1
В документации указано следующее:
Вы можете заставить обычную нетерпеливую выборку свойств с использованием
fetch all properties
в HQL.
Ссылки
- Справочное руководство по Hibernate Core
У меня есть объект Hibernate, свойства которого все загружены ленивыми. Большинство из этих свойств - другие объекты Hibernate или PersistentSets.
Теперь я хочу заставить Hibernate активно загружать эти свойства только один раз.
Конечно, я мог бы "прикоснуться" к каждому из этих свойств с помощью object.getSite().size()
, но, возможно, другой способ достичь моей цели.
В документации указано следующее:
Вы можете заставить обычную нетерпеливую выборку свойств с использованием
fetch all properties
в HQL.
Это старый вопрос, но я также хотел указать статический метод Hibernate.initialize
.
Пример использования:
Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
Теперь дети инициализируются для использования даже после закрытия сеанса.
Dozer работает хорошо для этого типа вещей - вы можете попросить Dozer сопоставить объект с другим экземпляром того же класса, и Dozer будет посещать все объекты, доступные из текущего объекта.
Подробнее см. этот ответ на аналогичный вопрос и мой ответ на другой связанный вопрос.
Для меня это работает:
Person p = (Parent) sess.get(Person.class, id);
Hibernate.initialize(p.getChildren());
Вместо этого:
Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
3 способа
1.HQL с левыми дочерними дочерними элементами
2.SetFetchMode после createCriteria
3.Hibernate.initialize
Это медленно, потому что он делает поездку в оба конца для каждого элемента, который требуется инициализировать, но он выполняет свою работу.
private void RecursiveInitialize(object o,IList completed)
{
if (completed == null) throw new ArgumentNullException("completed");
if (o == null) return;
if (completed.Contains(o)) return;
NHibernateUtil.Initialize(o);
completed.Add(o);
var type = NHibernateUtil.GetClass(o);
if (type.IsSealed) return;
foreach (var prop in type.GetProperties())
{
if (prop.PropertyType.IsArray)
{
var result = prop.GetValue(o, null) as IEnumerable;
if (result == null) return;
foreach (var item in result)
{
RecursiveInitialize(item, completed);
}
}
else if (prop.PropertyType.GetGenericArguments().Length > 0)
{
var result = prop.GetValue(o, null) as IEnumerable;
if (result == null) return;
foreach (var item in result)
{
RecursiveInitialize(item, completed);
}
}
else
{
var value = prop.GetValue(o, null);
RecursiveInitialize(value, completed);
}
}
}
Согласно зимуют документы, вы должны быть в состоянии отключить отложенную загрузку свойств, установив lazy
атрибут ваших конкретных отображений свойств:
<class name="Document">
<id name="id">
<generator class="native"/>
</id>
<property length="50" name="name" not-null="true"/>
<property lazy="false" length="200" name="summary" not-null="true"/>
<property lazy="false" length="2000" name="text" not-null="true"/>
</class>