On 11/30/2011 01:53 PM, Linda DeMichiel wrote:
>
>
> On 11/30/2011 7:26 AM, Emmanuel Bernard wrote:
>>
>> On 30 nov. 2011, at 00:48, Linda DeMichiel wrote:
>>
>>>>> Just to be very clear.... What are you referring to by "container
>>>>> level
>>>>> method
>>>>> invocation call"? The call to the entity manager proxy?
>>>>
>>>> Not the call to the entity manager proxy. I mean the code that is
>>>> calling the entity manager proxy (e.g. a session bean
>>>> calling the entity manager proxy.)
>>>>
>>>> Perhaps a clearer proposal could be:
>>>>
>>>> "
>>>> If the entity manager is invoked outside the scope of a transaction,
>>>> any entities loaded from the database will
>>>> immediately become detached at the end of the container level method
>>>> invocation call (e.g. when the session bean method
>>>> ends).
>>>> "
>>>
>>> Ah, thanks. That is not the intended semantics. Rather it is that the
>>> persistence context is created to service the method call that is made
>>> on the entity manager only. It doesn't have the duration of a business
>>> method invocation.
>>
>> Is it really?
>>
>
> Yes. See also section 3.8.7, which is quite explicit with regard to
> queries.
> BTW, these decisions date back to JPA 1.0 (aka EJB 3.0).
My updated proposal for the 7.6.2 wording is:
"
If the entity manager is invoked outside the scope of a transaction, any
entities loaded from the database will immediately become detached at
the end of the entity manager method call.
"
I was thinking more about the lazy associations problem. Is there room
in the JPA 2.1 specification, to make an enhancement that improves what
applications experience when the entity manager is invoked outside the
scope of a transaction? I'm thinking that the container could have a
way to give a hint to the persistence provider, that lazy fetching
should not be used for the entity manager invocation. The advantage of
this enhancement, is that applications will successfully be able to
access the loaded entity(s) that currently fail (due to lazy fetching
being used). I think that the application can also make changes to work
around this (e.g. use FetchType.EAGER) but I would like the same
(FetchType.LAZY) entity/association to work with both container/app
managed entity managers (that don't run in a JTA transaction).
Perhaps this could be a (new) standard property that the container could
pass to EntityManagerFactory.createEntityManager(Map) that suggests that
lazy fetching should be disabled. Or something more generic that covers
other possible problems. e.g. some hint like
"javax.persistence.auto-detach" that lets the provider know that loaded
entities will be detached (so the provider can avoid using lazy fetching).
>
>> I have to admit I am amongst people that read this as bound to the
>> duration of the business method call. The main problem with this
>> approach is that many em.find() calls are essentially useless as they
>> would not load (lazy) associations.
>> Upon detachment, the provider then raises a NotLoadedException of some
>> sort. The only way to work around that is to write a query with the
>> specific fetch pattern that ought to be used.
>> If entities are detached after the business call, the user can
>> navigate and use PersistenceUtil contracts to load the appropriate
>> part of the graph before ending the method.
>>
>> Note that for a PC that detaches entities upon EM method calls,
>> Hibernate has a specific API with specialized contracts to tailor that
>> kind of use case. I don't think our existing EM API is necessarily
>> well suited for that per se.
>>
>> Emmanuel