#20852 added support for Hibernate ORM's BeanContainer SPI, but the implementation ignores one of the parameters passed to the bean container: fallbackProducer. Hibernate ORM expects implementors to use this fallback producer whenever a bean could not be found (i.e., in the case of Spring, when the bean factory throws something like a BeanNotFoundException, I think).
Why it can be useful: for example, Hibernate Search uses the same SPI to instantiate some required beans, but provides a specific fallbackProducer which may in particular take advantage of a legacy annotation (@Factory, example). Even with advanced default behavior inside Spring's BeanFactory, Spring cannot reasonably be expected to understand that kind of annotation.
Ignoring this fallbackProducer parameter means that users migrating to Spring 5.1.RC1 who used to instantiate their beans through reflections or features native to Hibernate may have errors on startup because Spring doesn't find some beans, even though Hibernate would be able to find the beans by itself if given the chance.
An example of what was expected can be found in the CDI implementation built in Hibernate ORM:
Thanks for raising this, I wasn't aware that there may be more than plain default constructor invocation in a such a fallback producer... since I only checked Hibernate core itself. Spring's createBean is always able to instantiate such a plain class itself, so it didn't seem necessary to ever call the fallback producer.
So with such legacy @Factory classes, it looks like they can still be instantiated through a default constructor... @Factory just suggests a preferred factory method? That's a tough one since Spring's own creation attempt may succeed, so even with a fallback code path, we wouldn't actually end up there.
For better or for worse, for external autowiring purposes, Spring doesn't differentiate between 'known' and 'unknown' bean classes: It rather just tries to do the best to create an instance from the given class, running it through the constructor resolution algorithm and in particular through all of its post-processors. Since such processors may be customized, the factory cannot reliably infer whether those processors would specifically handle a given class. All it can do is to try to call the processors and see what it ends up with... even if for a simple bean class, nothing special is being applied other than calling the default constructor.
I've added a fallback to the Hibernate-provided producer for creation attempts that lead to a BeanCreationException, i.e. where there was no resolvable constructor which we could successfully invoke. This might cover your common @Factory cases, even if it doesn't give @Factory precedence over regular constructor invocations.
If there is anything else we can should do here, feel free to reopen this ticket.
Yoann Rodiere opened SPR-17010 and commented
#20852 added support for Hibernate ORM's BeanContainer SPI, but the implementation ignores one of the parameters passed to the bean container:
fallbackProducer
. Hibernate ORM expects implementors to use this fallback producer whenever a bean could not be found (i.e., in the case of Spring, when the bean factory throws something like a BeanNotFoundException, I think).Why it can be useful: for example, Hibernate Search uses the same SPI to instantiate some required beans, but provides a specific
fallbackProducer
which may in particular take advantage of a legacy annotation (@Factory, example). Even with advanced default behavior inside Spring's BeanFactory, Spring cannot reasonably be expected to understand that kind of annotation.Ignoring this
fallbackProducer
parameter means that users migrating to Spring 5.1.RC1 who used to instantiate their beans through reflections or features native to Hibernate may have errors on startup because Spring doesn't find some beans, even though Hibernate would be able to find the beans by itself if given the chance.An example of what was expected can be found in the CDI implementation built in Hibernate ORM:
As for tests, the built-in CDI implementation tests this exact feature (fallback instantiation) there: https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/test/java/org/hibernate/test/cdi/general/nonregistrymanaged/standard/NonRegistryManagedStandardCdiSupportTest.java#L110
Affects: 5.1 RC1
Issue Links:
Referenced from: commits d2eb4d2
The text was updated successfully, but these errors were encountered: