Программно указать ленивую загрузку для многих в один в спящем режиме - PullRequest
1 голос
/ 17 августа 2011

Я использую Hibernate 3.6 с Spring 3.0.5.

У меня есть следующее сопоставление для объекта User

<class name="foo.User" table="FOO_USER">
    <id  column="USER_ID" name="id" type="java.lang.Integer">
        <generator class="identity"/>
    </id>


    <property name="firstName" column="FIRST_NAME" type="java.lang.String" length="100"/>
    ...
    <many-to-one name="organization" column="ORGANIZATION_ID class="foo.Organization" not-null="true" update="false" />
    ...

Пользователь имеет отношение многие к одному с организацией,Обычно я хочу, чтобы эти отношения были загружены с нетерпением, поэтому отображение придерживается установки по умолчанию lazy = false (не указывая ничего).

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

(User)getSession().createCriteria(User.class)
            .add(Restrictions.eq("id",id))
            .setFetchMode("organization", FetchMode.SELECT)
            .uniqueResult();

Но режим выборки игнорируется.Hibernate все еще охотно загружает отношения Организации.Я стучу головой об это несколько часов.Любая помощь будет оценена.

Ответы [ 2 ]

3 голосов
/ 17 августа 2011

Всегда лучше оставлять сопоставления привязанными как ленивые и использовать стратегии извлечения для настройки производительности. Я не верю, что есть способ отобразить что-то как ленивое, а затем сделать его ленивым в конкретном случае. Конечно, fetch = select не сделает этого, так как это ничего не значит о лени. См. раздел 21.1 «Повышение производительности» в справочном руководстве для объяснения понятий.

1 голос
/ 09 июня 2013

FetchType может быть установлен программно с использованием fetchProfiles

например: Учтите, что существует класс Employee, и у него есть два дочерних класса. Профили Address и Department Fetch для них можно задать в классе Employee.

@FetchProfiles({ @FetchProfile(name = "emp_address", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "addresses", mode = FetchMode.JOIN) }), @FetchProfile(name = "emp_department", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "departments", mode = FetchMode.JOIN) })}) public class Employee {

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set addresses;

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set departments; }

Вы можете включить fetchprofile при получении записи Сотрудника.Если профиль извлечения включен, то дочерние объекты охотно выбираются, потому что вы выполняете объединение

session.enableFetchProfile("emp_address");
session.enableFetchProfile("emp_department");
Criteria criteria = session.createCriteria(Employee.class); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
List employees = criteria.list();
...