Загрузка прокси Hibernate только с первичным ключом - PullRequest
2 голосов
/ 06 сентября 2011

У нас есть следующие отношения:
Автомобиль принадлежит человеку.
Человек может владеть многими машинами.

Вот карта для автомобиля:

<hibernate-mapping package="fr.recouv.scribe.core.bo">
<class name="Car" table="car">
 <id name="id" column="id_car" unsaved-value="0">
  <generator class="sequence">
    <param name="sequence">car_id_car_seq</param>
  </generator>
</id>
<many-to-one name="person" update="false" column="id_person"  class="Person" /> 
<property 
</class>

У меня есть веб-сервис с этой подписью:

 public void insert(Car car, int idPersonOwner)

Я хочу вставить машину для конкретного человека с учетом его идентификатора. Прямо сейчас мой код выглядит так:

Car car = new Car();
Person owner = personDao.get(idPersonOwner);
car.setPerson(owner);
carDao.save(car);

А реализация hibernate для personDao.get (idPersonOwner) выглядит как

public Person  get(in idPerson){
return session.get(Person.class, id);
}

Недостаток этого метода :

  • объект all Person загружается, даже если мне нужно из представления SQL только его идентификатор
  • операция может генерировать БОЛЬШЕ, что 2 запроса, если отображение человека развивается (например, ленивая загрузка установлена ​​в false и т. Д.)

Мой фактический обходной путь : Это для прямого сопоставления внешнего ключа с целым числом

  <property column="id_person" name="idPerson" />

Это решение не является объектно-ориентированным и менее красивым. И если завтра мне нужно найти владельца автомобиля, я должен переназначить объект person, как предыдущий, и update = false

Можно ли загрузить ТОЛЬКО прокси-сервер Person с его идентификатором, что приведет к запросу проверить, существует ли этот человек с его первичным ключом, и при необходимости загрузить другие поля в режиме отложенного вызова, если они вызваны.

Я пробовал session.load, но это не решение. Объект никогда не является нулевым (нет запросов, проверяющих его существование), или никакие исключения не выдаются, пока вы не получите доступ к другому полю загрузить по-настоящему объект из базы данных.

1 Ответ

4 голосов
/ 06 сентября 2011

Да, именно для этого session.load (EntityManager.getReference при использовании JPA). Он загружает прокси для объекта, предполагая, что сущность существует.

Конечно, у вас может быть исключение, если во время фиксации ограничение внешнего ключа нарушается, потому что человек на самом деле не существует. Но у вас также может быть это с Session.get, если какая-то другая транзакция удаляет человека перед совершением.

Если вы действительно хотите проверить, существует ли человек, выполните специальный запрос, возвращающий только логическое значение (или число), и используйте Session.load, когда вы знаете, что человек существует:

Number count = 
    session.createQuery("select count(p.id) from Person p where p.id = :theId")
           .setLong("theId", theId)
           .uniqueResult();
if (count.intValue() > 0) {
    Person p = session.load(Person.class, theId);
}
else {
    // throw exception
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...