On Wed, Dec 20, 2017 at 9:48 AM, Sanne Grinovero <sa...@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 <yo...@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 > > yo...@hibernate.org > > _______________________________________________ > > hibernate-dev mailing list > > hibernate-dev@lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/hibernate-dev > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev