отключить загрузку собственности / коллекции с помощью Hibernate - PullRequest
0 голосов
/ 02 июня 2009

Кто-нибудь знает, как запретить загрузку коллекции или связь «многие-к-одному» в спящем режиме?

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

классы доменов:

public class SomeClass {
    private SomeClass parent;
    private Set<OtherClass> collection;
}

public class OtherClass {
    private Date startDate;
    private Date endDate;
}

public class Dao {
    public SomeClass loadClass(long id, boolean parents, boolean historicalData) {
         // load SomeClass
         // if parents == true, load parent, otherwise leave <null>
         // if historicalData == false, load OtherClass where endDate == <null>
    }
}

Я подумал о 2 решениях, но сейчас я перейду, если это возможно, с помощью критерия или запроса.

Решение 1 состоит в том, чтобы не связывать SomeClass с OtherClass и отношения родитель / потомок в конфигурации гибернации и загружать сопоставление в коде.
Решение 2 состоит в том, чтобы определить различные сопоставления с разными именами сущностей для особых случаев.

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

Ответы [ 4 ]

2 голосов
/ 02 июня 2009

Для этого вы должны использовать функции отложенной загрузки Hibernate. Вы можете аннотировать коллекцию как:

@OneToMany(fetch=FetchType.LAZY)

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

1 голос
/ 02 июня 2009

Напишите запрос Criteria и используйте метод setFetchMode, чтобы изменить поведение выборки для родительского метода, а метод createCriteria для дополнительного запроса к коллекции.

Criteria c = session.createCriteria(SomeClass.class).add(Restrictions.idEq(id));

if (parents) {
  c.setFetchMode("parents", FetchMode.EAGER);
}
if (historicalData) {
  c.createCriteria("collection", Criteria.LEFT_JOIN)
   .add(Restriction.lt("date", date))
   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
return c.uniqueResult();

... это при условии, что по умолчанию установлено значение LAZY (согласно Hibernate по умолчанию).

В Hibernate нет возможности оставлять свойства null , которые имеют значение (в данном случае это сопоставление "многие к одному". Поле будет содержать прокси, который можно использовать для ленивой загрузки упомянутый объект. Если код никогда не касается объекта, он не будет загружен.

То же самое верно для коллекции: если она не извлечена, она будет содержать прокси-сервер коллекции (класс гибернации, реализующий интерфейс коллекции), который будет загружать содержимое только при вызове.

0 голосов
/ 02 июня 2009

Я думаю, что # 2 - лучшее решение. Хотя я сам не использовал это решение, я знаю других разработчиков, которые добились успеха.

0 голосов
/ 02 июня 2009

Используйте @OneToMany(fetch=FetchType.LAZY), как сказано выше, но имейте в виду, что ленивая выборка коллекций и ассоциаций является типом выборки по умолчанию в Hibernate 3.x.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...