lately I experimented a little with JPA to try to understand the whole framework a little more. I am using Eclipselink as JPA provider.
I have two entities with a @OneToMany
relationship (one person has many addresses) that is lazy loaded.
When I load a person entity, detach it and then try to access the (not loaded) addresses... it works as a charm. When debugging I can see that a database query is executed when executing the size()
method of the address list.
I do not understand why that works. I would expect some kind of exception. I have read quite a few about jpa and the like in the last days (i. e. this link) but everything pointed me to the conclusion that it should not work.
Can anyone please explain why that works?
@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);
}
}
The resulting log would be
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}]}}
As described here detach removes the Entity from the context so that it is no longer managed. Since the context is still available though, untriggered lazy collections can still be fetched if needed, and EclipseLink felt this more valuable than throwing an exception. This is considered a feature of EclipseLink, and is allowed by the JPA spec despite other providers not enabling the behavior by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With