Принудительная загрузка других ленивых загружаемых свойств

У меня есть объект Hibernate, свойства которого все загружены ленивыми. Большинство из этих свойств - другие объекты Hibernate или PersistentSets.

Теперь я хочу заставить Hibernate активно загружать эти свойства только один раз.

Конечно, я мог бы "прикоснуться" к каждому из этих свойств с помощью object.getSite().size(), но, возможно, другой способ достичь моей цели.

Ответ 1

В документации указано следующее:

Вы можете заставить обычную нетерпеливую выборку свойств с использованием fetch all properties в HQL.

Ссылки

Ответ 2

Это старый вопрос, но я также хотел указать статический метод Hibernate.initialize.

Пример использования:

Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());

Теперь дети инициализируются для использования даже после закрытия сеанса.

Ответ 3

Dozer работает хорошо для этого типа вещей - вы можете попросить Dozer сопоставить объект с другим экземпляром того же класса, и Dozer будет посещать все объекты, доступные из текущего объекта.

Подробнее см. этот ответ на аналогичный вопрос и мой ответ на другой связанный вопрос.

Ответ 4

Для меня это работает:

Person p = (Parent) sess.get(Person.class, id);
Hibernate.initialize(p.getChildren());

Вместо этого:

Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());

Ответ 5

3 способа

1.HQL с левыми дочерними дочерними элементами

2.SetFetchMode после createCriteria

3.Hibernate.initialize

Ответ 6

Это медленно, потому что он делает поездку в оба конца для каждого элемента, который требуется инициализировать, но он выполняет свою работу.

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

Ответ 7

Согласно зимуют документы, вы должны быть в состоянии отключить отложенную загрузку свойств, установив 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>