В последнее время я немного экспериментировал с JPA, чтобы попытаться понять всю структуру немного больше. Я использую Eclipselink как поставщик JPA.Метод вызова JPA на ленивой (не загруженной) коллекции при отсоединении не работает, как ожидалось, в Eclipselink
У меня есть два объекта с отношением @OneToMany
(один человек имеет много адресов), который лениво загружен.
Когда я загружаю лицо человека, отсоединяю его, а затем пытаюсь получить доступ к (не загруженным) адресам ... он работает как прелесть. При отладке я вижу, что запрос базы данных выполняется при выполнении метода списка адресов size()
.
Я не понимаю, почему это работает. Я бы ожидал какого-то исключения. Я читал немало о jpa и т. П. В последние дни (то есть this link), но все указывало на то, что он не должен работать.
Может кто-нибудь объяснить, почему это работает?
@Stateless
public class Test {
@PersistenceContext(unitName="TestPU") EntityManager em;
public void test() {
Person person = em.find(Person.class, 1);
System.out.println(person);
System.out.println("em.contains(person): " + em.contains(person);
em.detach(person);
System.out.println("em.contains(person): " + em.contains(person);
person.getAddresses().size();
System.out.println("em.contains(person): " + em.contains(person);
System.out.println(person);
}
}
В результате журнал будет
DEBUG: SELECT ... from PERSON WHERE (id = ?)
Person{id=1, name=Test, addresses={IndirectList: not instantiated}}
em.contains(person): true
em.contains(person): false
DEBUG: SELECT ... FROM ADDRESSES where (address_fk = ?)
em.contains(person): false
Person{id=1, name=Test, addresses={[Address{id=10, city=Testcity}]}}
потому что с EclipseLink они на самом деле не «отделяют» объекты от того, как намеревается спецификация JPA (т.е. отсоединяется от БД), поэтому они сохраняют информацию о подключении ... следовательно, она извлекает поле (хотя оно не должно если действительно «отделился»). Если вы выполняли ту же операцию с другими поставщиками JPA, они обычно генерировали исключение, если поле не было отключено. –
Вы можете проверить, правильно ли удален объект, вызвав [em.contains] (http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#contains%28java.lang.Object % 29) –