Description
Problem
In contrast to anonymous classes, lambda expressions do not carry generics information. If an entity callback is declared as Spring bean like this:
@Bean
BeforeSaveCallback<Person> someCallback() {
return person -> { … };
}
the inspection of the instance returned for the generic entity type will still see Object
, not Person
. If the implementation had been declared as new BeforeSaveCallback<Person>() { … }
, the generics information would be available.
This lack of type information impedes selecting the correct set of entity callbacks on invocation. We currently work around this by invoking all listeners that take Object
as parameters (i.e. the ones declared as lambdas) and handle the ClassCastException
resulting from a potentially invalid invocation. As a CCE
can also result from the callback execution in general, we have to deeply inspect the exception, which requires Java version-specific handling and has caused trouble supporting newer Java versions as apparently the internals of a CCE change frequently.
Solution
When we look up the EntityCallback
instances from the BeanFactory
we can fall back to inspecting the BeanDefinition
for its generic type, and as that resolves to the return type used on the bean's factory method, we can use that instead of only seeing Object
.