Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of EntityCallback bean declarations declared as lambdas #2812

Closed
odrotbohm opened this issue Apr 4, 2023 · 0 comments
Closed
Assignees
Labels
in: core Issues in core support

Comments

@odrotbohm
Copy link
Member

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.

@odrotbohm odrotbohm added the in: core Issues in core support label Apr 4, 2023
@odrotbohm odrotbohm added this to the 3.0.5 (2022.0.5) milestone Apr 4, 2023
@odrotbohm odrotbohm self-assigned this Apr 4, 2023
@odrotbohm odrotbohm changed the title Improve handling of EntityCallback bean declaration declared as lambdas Improve handling of EntityCallback bean declarations declared as lambdas Apr 4, 2023
odrotbohm added a commit that referenced this issue Apr 4, 2023
In case an EntityCallback is declared as lambda expression, the JVM does not expose any generics information about the target entity type the callback shall be applied to. This commit changes the callback lookup and processing so that in case the generics information is not detectable on the type, we fall back to the BeanDefinition's resolvable type (fed by the factory method's return type which carries the necessary reflection information). That generics information is then kept in the newly introduce EntityCallbackAdapter and the code inspecting the actual entity type for matches then uses the resolvable type held in that. Also, the actual callback invocation is done on the adapter's delegate.

Removed the ability of the discoverer to register EntityCallbacks by bean name as that was not used in the public API at all and it avoids duplicating the bean definition type detection. A couple of minor additional cleanups (records for cache key, methods static where possible and with lower visibility etc.)

Fixes #2812.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core support
Projects
None yet
Development

No branches or pull requests

1 participant