On 7/29/2011 2:32 AM, Emmanuel Bernard wrote:
>
>>>> * An entity listener class that is defined as a @BeanListener
>>>> may specify PostConstruct and PreDestroy methods. These methods
>>>> will be invoked by the provider after injection has taken
>>>> place and before the entity listener instance is destroyed respectively.
>>> That should be taken care of by use of the CDI SPI to allocate and destroy entity listeners. The provider should not
>>> need to invoke them directly, and may land up invoking them again if CDI has already done so.
>>>
>>
>> Right. The persistence provider calls into CDI to have these methods invoked.
>
> Oh, hold on.
> You want CDI to be responsible for invoking @PostConstruct / @PreDestroy, correct?
Right
> What happens if CDI is not present in the environment and that the provider is instanciating the EntityListeners itself?
> Should it call these methods?
>
Well, I was going to define that if @BeanListener weren't specified, these methods weren't
supported, and if the listener specified them it wasn't well-formed.
However, what do you all think?
> In any case, I think the spec should be clearer as to who calls these methods when CDI is in used.
>
>>
>>> Perhaps: "If any no-argument method annotated @PostConstruct is found on an entity listener annotated with
>>> @BeanListener, this method must be invoked exactly once after the constructor and initializer have run and before any
>>> other methods are called."
>>>
>>> I don't think this section will matter anyway if CDI-enabled listeners become managed beans, as I suspect will need to
>>> happen. See below.
>>>
>>>> Finally, just to be very clear about this, an entity listener
>>>> would thus be, in CDI terminology, an "unmanaged object".
>>>> In other words, it would receive CDI injections, would not itself
>>>> be available for injection into other CDI-managed beans.
>>>
>>> At first reading I didn't see any reason to make entity listeners managed objects. After writing my comments on
>>> lifecycle below, though, I realized that they probably should be because (IMO) they need to be able to be scoped and
>>> because injection is nearly useless without context.
>>>
>>
>> The context would need to be that of the calling component.
>
By context, I meant referencing environment. This applies even if there
is no CDI in the loop. I.e., if the entity listener accesses JNDI, it is
getting the referencing environment of the calling component. (I.e.,
I was using "context" in the general Java EE sense rather than the technical
CDI sense. Sorry for any confusion on this point.)
> Right the "context" in this case is manually handled by the persistence provider. Some might chose per instance object creation while others might chose one instance shared by all invocations. The context in essence is defined by calling BeanManager's create / destroy operations with the bean instance as a param.
>
>>
>>>
>>> The JPA 2.0 spec states that:
>>>
>>> "Entity listeners are stateless. The lifecycle of an entity listener is unspecified."
>>>
>>> Is that necessarily going to be useful for a listener subject to injection?
>>>
>>
>> I'd like to have the group discuss what we say about the lifecycle issue. AFAICT, however,
>> the safest approach seems to be the creation of listener instances per invocation.
>
> It is still useful even if the listener itself is stateless. Remember that while the listener context is handled by the JPA provider, the injected components them selves can be scoped. So to take Craig's example, you could get a listener injecting a component return the request scoped username.
> In practice, this is implemented via proxying by CDI implementations.
>
Right, I was assuming that for proxyable objects. However, for dependent objects, does it or does
it not make a difference as to whether the component that causes the listener to be instantiated
is a different component from the one on whose behalf a given lifecycle callback occurs?
I.e., does adding this functionality mean that we need to nail down more specifically what
the lifetime of such an entity listener is?
> BTW we should mention that an EL cannot directly or indirectly inject the persistence context it comes from.
Cannot or *should not*? I was assuming "should not".
thanks again,
-Linda