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

Yoann Rodiere yoann at hibernate.org
Wed Dec 20 10:08:36 EST 2017

> 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

Not sure what you mean by that. Currently the DI framework doesn't know who
uses these components, and therefore it's up to us to tell the DI framework
when they can be "destroyed".
Do you suggest that we make the DI framework aware of the Hibernate ORM =>
<some beans> dependency, and let it do what it can to handle that

I know this would work (and probably is already doable without much change)
in Spring, because in Spring DI the EntityManagerFactory is viewed as just
another type of bean, and therefore its whole lifecycle is already handled
by Spring DI.
In WildFly though, things are a little bit different: from what I
understood, WildFly starts the persistence units (Hibernate ORM)
explicitly, and only then it starts the CDI context (Weld). And the
opposite when shutting down. The persistence units lifecycle really isn't
integrated into CDI... But maybe it should be. In particular the ability to
lazily load the persistence units when they are first requested by a CDI
bean, and to automatically close a persistence unit when no CDI bean
depends on it anymore, would solve a lot of dependency issues. Or at least
it would move the problems out of our scope.
However, I'm not sure that such behavior would be compatible with all the
specs WildFly must comply with.

Yoann Rodière
Hibernate NoORM Team
yoann at hibernate.org

On 20 December 2017 at 15:48, 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.
> >
> > #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