[hibernate-dev] CDI integration in Hibernate ORM and the Application scope

Scott Marlow smarlow at redhat.com
Wed Jan 3 11:09:12 EST 2018


On Tue, Jan 2, 2018 at 2:42 PM, Steve Ebersole <steve at hibernate.org> wrote:

> Scott, how would we register a listener for this event?
>

If we want a standard solution, we could ask for an earlier CDI pre-destroy
listener.

The problem we have had with most CDI "listeners" so far is that they are
> non-contextual, meaning there has been no way to link that back to a
> specific SessionFactory..  If I can register this listener with a reference
> back to the Sessionfactory, this should actually be fine.
>

I could pass the EMF to the
org.hibernate.jpa.event.spi.jpa.ExtendedBeanManager.LifecycleListener,
if that helps.


>
> On Tue, Jan 2, 2018 at 1:39 PM Scott Marlow <smarlow at redhat.com> wrote:
>
>> On Wed, Dec 20, 2017 at 9:48 AM, Sanne Grinovero <sanne at hibernate.org>
>> wrote:
>>
>> > Any dependency injection framework will have some capability to define
>> > the graph of dependencies across components, and such graph could be
>> > very complex, with details only known to the framework.
>> >
>> > I don't think we can solve the integration by having "before all
>> > others" / "after all others" phases as that's too coarse grained to
>> > define a full graph; we need to find a way to have the DI framework
>> > take in consideration our additional components both in terms of DI
>> > consumers and providers - then let the framework wire up things in the
>> > order it prefers. This is also to allow the DI engine to print
>> > appropriate warnings for un-resolvable situations with its native
>> > error handling, which would resolve in more familiar error messages.
>> >
>> > If that's not doable *or a priority* then all we can do is try to make
>> > it clear enough that there will be limitations and hopefully describe
>> > these clearly. Some of such limitations might be puzzling as you
>> > describe.
>> >
>> >
>> >
>> > On 20 December 2017 at 12:50, Yoann Rodiere <yoann at hibernate.org>
>> wrote:
>> > > Hello all,
>> > >
>> > > TL;DR: Application-scoped beans cannot be used as part of the
>> @PreDestroy
>> > > method of ORM-instantiated CDI beans, and it's a bit odd because they
>> can
>> > > be used as part of the @PostConstruct method.
>> > >
>> > > I've been testing the CDI integration in Hibernate ORM for the past
>> few
>> > > days, trying to integrate it into Search. I think I've discovered
>> > something
>> > > odd: when CDI-managed beans are destroyed, they cannot access other
>> > > Application-scoped CDI beans anymore. Not sure whether this is a
>> problem
>> > or
>> > > not, so maybe we should discuss it a bit before going forward with the
>> > > current behavior.
>> > >
>> > > Short reminder: scopes define when CDI beans are created and
>> destroyed.
>> > > @ApplicationScoped is pretty self-explanatory: created when the
>> > application
>> > > starts and destroyed when it stops. Some other scopes are a bit more
>> > > convoluted: @Singleton basically means created *before* the
>> application
>> > > starts and destroyed *after* the application stops (and also means
>> "this
>> > > bean shall not be proxied"), @Dependent means created when an
>> instance is
>> > > requested and destroyed when the instance is released, etc.
>> > >
>> > > The thing is, Hibernate ORM is typically started very early and shut
>> down
>> > > very late in the CDI lifecycle - at least within WildFly. So when
>> > Hibernate
>> > > starts, CDI Application-scoped beans haven't been instantiated yet,
>> and
>> > it
>> > > turns out that when Hibernate ORM shuts down, CDI has already
>> destroyed
>> > > Application-scoped beans.
>> > >
>> > > Regarding startup, Steve and Scott solved the problem by delaying bean
>> > > instantiation to some point in the future when the Application scope
>> is
>> > > active (and thus Application-scoped beans are available). This makes
>> it
>> > > possible to use Application-scoped beans within ORM-instantiated
>> beans as
>> > > soon as the latter are constructed (i.e. within their @PostConstruct
>> > > methods).
>> > > However, when Hibernate ORM shuts down, the Application scope has
>> already
>> > > been terminated. So when ORM destroys the beans it instantiated, those
>> > > ORM-instantiated beans cannot call a method on referenced
>> > > Application-scoped beans (CDI proxies will throw an exception).
>> > >
>> > > All in all, the only type of beans we can currently use in a
>> @PreDestroy
>> > > method of an ORM-instantiated bean is @Dependent beans. @Singleton
>> beans
>> > > will work, but only because they are not proxied and thus you can
>> cheat
>> > and
>> > > use them even after they have been destroyed... which I definitely
>> > wouldn't
>> > > recommend.
>> > >
>> > > I see two ways to handle the issue:
>> > >
>> > >    1. We don't change anything, and simply document somewhere that
>> beans
>> > >    instantiated as part of the CDI integration are instantiated within
>> > the
>> > >    Application scope, but are destroyed outside of it. And we suggest
>> > that any
>> > >    bean used in @PostDestroy method in an ORM-instantiated bean
>> > (directly or
>> > >    not) must have either a @Dependent scope, or a @Singleton scope
>> and no
>> > >    @PostDestroy method.
>> > >    2. We implement an "early shut-down" somehow, which would bring
>> > forward
>> > >    bean destruction to some time when the Application scope is still
>> > active.
>> >
>>
>> org.hibernate.jpa.event.spi.jpa.ExtendedBeanManager mentions that we
>> could
>> look at introducing a beanManagerDestroyed notification, if that is useful
>> and we can find a way to implement it (javax.enterprise.spi.
>> BeforeShutdown
>> [1] is not early enough to meet your requirements).
>>
>> Scott
>>
>> [1]
>> https://docs.oracle.com/javaee/7/api/javax/enterprise/
>> inject/spi/BeforeShutdown.html
>>
>>
>> > >
>> > > #1 may be enough for now, even though the behavior feels a bit odd,
>> and
>> > > forces users to resort to less-than-ideal practices (using a
>> @Singleton
>> > > bean after it has been destroyed).
>> > >
>> > > #2 would require changes in WildFly and may be a bit complex. In
>> > > particular, if we aren't careful, Application-scoped beans may not be
>> > able
>> > > to use Hibernate ORM from within their @PreDestroy methods... Which is
>> > > probably not a good idea. So we would have to find a solution together
>> > with
>> > > the WildFly team. Also to be considered: Hibernate Search would have
>> to
>> > be
>> > > shut down just before the "early shut-down" of Hibernate ORM occurs,
>> > > because Hibernate Search cannot function at all without the beans it
>> > > retrieves from the CDI context.
>> > >
>> > > Thoughts?
>> > >
>> > >
>> > > Yoann Rodière
>> > > Hibernate NoORM Team
>> > > yoann at hibernate.org
>> > > _______________________________________________
>> > > hibernate-dev mailing list
>> > > hibernate-dev at lists.jboss.org
>> > > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>> >
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
>


More information about the hibernate-dev mailing list