-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
NPE when injecting EntityManager/EntityManagerFactory into ObjectMapperCustomizer #9049
Comments
Unfortunately this can't reall work as expected due to timing issues. What exactly are you trying to do? Asking because it might be something we can do inside the Jackson extension (by providing optional integration with the hibernate extension). |
I'm trying to implement some Deserializer/BeanDeserializerModifier for a bunch of entities. In my case: entities that implement a certain interface. Pseudocode:
|
I see, so all you need are the entity classes, right? |
entities (and for future use) maybe everything that's available via MetaModel |
@Sanne is there any way that an arbitrary piece of Quarkus code could find the entities found at build time? Obviously it's possible, so my question is more whether we have anything like that in place |
We don't create the EntityManager producer when there are no entities. I believe a way to find them is to depend on the buildItem |
ah sorry it appears I misunderstood the question. You don't want to have the list at build time :)
Yes that's correct; however to have an EntityManager started requires having a datasource to be configured as well. |
For the time being, just being able to grab the list of entities (their classes to be precise) from arbitrary code would be enough I think. |
But do you need it at build time or runtime? If runtime, what do you expect to see as API? |
In this case, the OP needs them at runtime in order to customize Jackson. But I was also wondering if it made sense for us to know them at build so we can enable some kind of customization of Jackson ourselves if necessary. |
You can get them at build time easily as there are Regarding Jackson, I'd say the ideal solution is to also generate this all at build time. If that's too complicated, perhaps you can use some ArC API to see if you can get an EntityManager ? If there is no entity manager factory, then there are no managed entities - which is what I suppose matters here? Of course you might still miss to find classes annotated with |
The build iteams which might be relevant are |
Thanks @Sanne |
@HonoluluHenk How does this design sound: Quarkus would provide an What do you think? |
yeah, that'd solve my problem. Problem I foresee with this solution: if another usecase arises where you not only need Hibernate entities but also some other resources from other extensions (of which we do not yet have an idea yet), you'd need an AbstractOtherStuffObjectMapperCustomizer.... and then lateron some AbstractMoreStuffObjectMapperCustomizer.... ad infimum. But: the Application only may extend one of these. One idea to remedy this (but I have no idea if that's possible!): Quarkus provides some buildtime-injectable bean (like e.g. Usage might then look like this: @Singleton
public class RegisterCustomModuleCustomizer implements ObjectMapperCustomizer {
@Inject
QuarkusHibernateEntityEnumerator entityEnumerator;
public void customize(ObjectMapper mapper) {
doMyThing(entityEnumerator.enumerateEntities(), mapper);
}
} Another idea this time building on your implementation, tryingo to remedy the aforementioned problem: public abstract class AbstractObjectMapperCustomizer implements ObjectMapperCustomizer {
protected final <T extends QuarkusBuildtimeInfo> Optional<T> findBuildtimeInfo(Class<? extends T> implementation) {
...
}
} and then - for now the only implementation - the Hibernate extension e.g.: interface HibernateBuildtimeInfo extends QuarkusBuildtimeInfo {
Set<Class<?>> getEntityClasses();
} I could then use this construct as follows: @Singleton
public class MyCystomizer extends AbstractObjectMapperCustomizer {
@Override
public void customize(ObjectMapper mapper) {
findBuildtimeInfo(HibernateBuildtimeInfo.class)
.map(HibernateBuildtimeInfo::getEntityClasses)
.map(entityClasses -> doMyThing(entityClasses, mapper).
.orElseThrow(() -> new IllegalStateException("HibernateBuildtimeInfo not found?"));
}
} |
I like the first solution a lot, it's very straightforward! |
@geoand I just looked into your commits and like them alot 👍 Imho the 99% use case is to use the Entity classes, not their stringified class name. |
@HonoluluHenk that sounds reasonable, but I am hesitant to do for a couple of reasons:
So I think it's best left up to client code to load the classes (via the Thread Context ClassLoader) |
I created PR geoand#5 to care for these 2 problems... |
Is this still an issue? |
Closing for lack of feedback |
Describe the bug
I implemented the Jackson ObjectMapperCustomizer and tried to @Inject the Hibernate EntityManager or EntityManagerFactory.
On quarkus:dev startup, a NullPointerException gets thrown:
Expected behavior
Application should start, EM/EMF should get injected.
Actual behavior
NPE, see description
To Reproduce
Steps to reproduce the behavior:
Configuration
N/A
Screenshots
N/A
Environment (please complete the following information):
Additional context
Most specific stacktrace entry:
The text was updated successfully, but these errors were encountered: