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

Scott Marlow smarlow at redhat.com
Tue Jan 2 14:37:35 EST 2018


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
>


More information about the hibernate-dev mailing list