2012-06-13 2 views
4

Мой вопрос касается EntityManager.getReference. Учитывая, что я нахожусь в одном сеансе JPA, могу ли я быть уверенным, что для двух вызовов EntityManager.getReference для одного и того же объекта и одного и того же первичного ключа я всегда получаю один и тот же экземпляр объекта java? Для двух разных сеансов я подозреваю, что получаю два разных экземпляра Java-объектов - действительно ли это так?EntityManager.getReference всегда возвращает один и тот же экземпляр внутри сеанса?

Мне интересно знать общее правило, а не то, как работает какая-либо конкретная реализация. Определяется ли это спецификацией или нет? (Я не смог сам это выяснить).

Person p1 = EntityManager.getReference(Person.class, 1L); 
Person p2 = EntityManager.getReference(Person.class, 1L); 

if (p1 == p2) { 
    System.out.println("SAME"); 
} else { 
    System.out.println("DIFF"); 
} 
+0

Возможно, это поможет: http: // stackoverflow.com/questions/1607532/when-to-use-entitymanager-find-vs-entitymanager-getreference – JMelnik

ответ

2

Да, это основная гарантия JPA - в пределах контекста инерционности (т.е. сессии, EntityManager) объект Идентичности удалась объектов спичек своей идентичности базы данных:

7.1 Стойкость контексты

Контекст сохранения - это набор экземпляров управляемых сущностей, в которых для любого постоянного идентификатора сущности существует уникальный экземпляр объекта.

и getReference() возвращает управляемый экземпляр:

3.2.8 управляемых экземпляров

...

класс содержит() метод может быть использован, чтобы определить, является ли сущности экземпляр управляется в текущем контексте сохранения.

содержит метод возвращает истину:

  • Если объект был получен из базы данных или были возвращены на getReference, и не был удален или отдельно.
  • Если экземпляр объекта является новым и метод persist был вызван в сущности, или операция persist была каскадирована на него.

Кроме того, эта гарантия означает, что внутри рамки контекста инерционности вы получите тот же экземпляр объекта для того же идентификатора, независимо от того, как вы получили его (через find(), getReference(), merge(), запроса или отношения обход).

Например, если вы получили прокси из getReference() все дальнейшие работы с этим объектом будет происходить через этот прокси-сервер:

Person p1 = EntityManager.getReference(Person.class, 1L); 
Person p2 = EntityManager.find(Person.class, 1L); 
assertSame(p1, p2); 

Смотрите также:

+0

Большое спасибо за этот исчерпывающий ответ - это было очень полезно –

Смежные вопросы