Спящий режим изменения режима выборки во время выполнения

У меня есть две таблицы, связанные друг с другом с помощью отношения «один ко многим»: сотрудник -> отдел: и отношение через «department_id» в таблице сотрудников.

Я использую hibernate : и мои файлы отображения гибернации:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping default-lazy="false">
 <class catalog="moi"
  name="com.ebla.moi.correspondence.model.entity.user.User" table="user">
  <id name="id" type="java.lang.Long">
   <column name="id"/>
   <generator class="identity"/>
  </id>
  <many-to-one
   class="com.ebla.moi.correspondence.model.entity.department.Department"
   fetch="select" name="department">
   <column name="department_id"/>
  </many-to-one>
  <property generated="never" lazy="false" name="name" type="java.lang.String">
   <column length="128" name="name" not-null="true"/>
  </property>
  <property generated="never" lazy="false" name="email" type="java.lang.String">
   <column length="128" name="email" not-null="true" unique="true"/>
  </property>
  <property generated="never" lazy="false" name="maritalStatus" type="java.lang.Short">
   <column name="marital_status" not-null="true"/>
  </property>
  <property generated="never" lazy="false" name="hireDate" type="java.lang.String">
   <column length="64" name="hire_date"/>
  </property>
 </class>
</hibernate-mapping>

и второй файл сопоставления:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping default-lazy="false">
 <class catalog="moi"
  name="com.ebla.moi.correspondence.model.entity.department.Department" table="department">
  <id name="id" type="java.lang.Long">
   <column name="id"/>
   <generator class="identity"/>
  </id>
  <property generated="never" lazy="false" name="name" type="java.lang.String">
   <column length="256" name="name" unique="true"/>
  </property>
  <set inverse="true" name="users" sort="unsorted">
   <key>
    <column name="department_id"/>
   </key>
   <one-to-many class="com.ebla.moi.correspondence.model.entity.user.User"/>
  </set>
 </class>
</hibernate-mapping>

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

благодарю вас


person Community    schedule 02.02.2009    source источник


Ответы (4)


Вы можете сопоставить отношение как «ленивое» и написать два запроса для получения ваших данных:

  • Обычный простой запрос на получение ваших данных ("ленивый"). Например. "выберите e из Employee e, где..."

  • Тот же запрос с использованием «выборки соединения», чтобы заставить Hibernate извлекать «дочерние элементы». Например. «выберите e из Employee left join fetch e.department, где …»

ТОО, Андреа

person andcoz    schedule 02.02.2009

Вы можете использовать ICriteria для получения вашего сотрудника.

Вы можете использовать метод SetFetchMode ICriteria, чтобы определить, следует ли извлекать отдел или нет:

Это гарантирует, что отдел не будет извлечен:

ICriteria crit = theSession.CreateCriteria (typeof(Employee));
crit.SetFetchMode ("Department", FetchMode.Lazy)

С этим кодом отдел будет получен.

ICriteria crit = theSession.CreateCriteria (typeof(Employee));
crit.SetFetchMode ("Department", FetchMode.Join)

Некоторые говорят, что лучше всего использовать режим выборки по умолчанию в сопоставлениях (что, я думаю, было бы лениво) и указывать режим выборки в каждом конкретном сценарии. (То есть в ваших репозиториях).

person Frederik Gheysels    schedule 02.02.2009
comment
Это не работает для меня. Он по-прежнему извлекает связанные объекты, но не использует предложение соединения. Вместо этого он вызывает другой оператор выбора. - person supertonsky; 30.04.2012

Один из способов сделать это — иметь два класса, представляющих сотрудника:

  • Employee, в котором отображается информация об отделе;
  • EmployeeSummary, в котором есть только сами данные о сотрудниках.

Тогда оба класса имеют независимые привязки к таблице employee, но только Employee также имеет определенную связь с department.

Затем, когда вам нужна вся информация, вы загружаете Employee экземпляров, а когда вам нужна только информация о сотрудниках, вы загружаете EmployeeSummary экземпляров.

Вы можете удалить любое дублирование привязок ORM и бизнес-логики, введя общий суперкласс, такой как AbstractEmployee, для обоих классов сотрудников.

person Dan Vinton    schedule 02.02.2009
comment
Не думаю, что это хорошая идея в данной ситуации. Что делать, если ваши классы содержат сложные BL? Вам придется дублировать его? - person Frederik Gheysels; 02.02.2009
comment
Не обязательно, если вы введете общий суперкласс, но хороший момент - я обновил ответ, чтобы отразить это. - person Dan Vinton; 02.02.2009
comment
Что, если в одном сеансе и Employee, и EmployeeSummary были загружены из одной и той же записи базы данных, а затем один или оба из них были изменены? - person Ian Ringrose; 02.02.2009
comment
Это может произойти в любом случае — что, если два экземпляра записи о сотруднике были загружены и изменены независимо друг от друга? Надеюсь, ваше поле номера версии Hibernate спасет вас в любом случае... - person Dan Vinton; 02.02.2009

Я думаю, что вы ищете выбор профилей . Также взгляните на этот пример: http://arjan-tijms.omnifaces.org/2012/04/fetching-arbitrary-object-graphs-in-jpa.html

person Priyank Doshi    schedule 26.10.2012