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

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

Классы домена:

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

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

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

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

0
Salandur 2 Июн 2009 в 17:52

4 ответа

Лучший ответ

Напишите запрос 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 , у которых есть значение (в данном случае связь "многие к одному". Поле будет содержать прокси-сервер, который можно использовать для ленивой загрузки указанного объекта. .Если код никогда не касается объекта, он не загружается.

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

1
Maarten Winkels 2 Июн 2009 в 18:42

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

0
BacMan 2 Июн 2009 в 14:40

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

0
GreenieMeanie 2 Июн 2009 в 14:11

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

@OneToMany(fetch=FetchType.LAZY)

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

2
Kees de Kooter 2 Июн 2009 в 14:09