Payara: CDI Injection in EntityListener fails when AttributeConverter is present during deployment

Created on 12 Feb 2019  路  4Comments  路  Source: payara/Payara

# Description #

CDI injection into an EntityListener fails if you also use an AttributeConverter.
This relates to my previously filled bug #3121. But this time i can reproduce it.

Expected Outcome

CDI injection into an entity listener always works.

Current Outcome

If you deploy a project with an EntityListener and an AttributeConverter the injection into the listener fails.

Steps to reproduce

  1. Check out and build:
    https://github.com/TheOnlyAl/entitylistener-bug

  2. Deploy the war on Payara. Easiest way is to use the docker image:
    docker run -p 4848:4848 -p 8080:8080 payara/server-full:5.184

After deployment you will see: "Could not inject AuditEntityListenerServiceBean!" in the log file.

If you remove the Converterfrom the Entityhere the injection works and you will get the date of the persist operation.

Context

The only workaround currently is to remove all AttributeConverter's or do a manual lookup of the Bean in the EntityListener. In my example I use an EJB for the injection target, but CDI beans should also fail.

The problem is that if the JPADeployer finds any AttributeConverter's during deployment it tries to create the InjectionManager, which will fail since the BeanManager can not be looked up, and therefore fallback to the DisabledInjectionManager.
If no AttributeConverter is registered, the InjectionManager is created after the deployment and the BeanManager lookup does not fail. This is why the injection works fine without and AttributeConverter

I tested this on 5.183 and 5.184.

Environment

  • Payara Version: 5.183, 5.184
  • Edition: Full
  • JDK Version: OpenJDK 1.8.0_191
  • Operating System: Linux (Debian)
  • Database: Postgres
Accepted Bug

Most helpful comment

Hi Alexander,

Thank you for the updated version of the reproducer.
I have created an internal issue for our engineers to fix the problem you describe. When JPA Persistence Unit starts deploying, CDI module should be ready so I'm not sure what could be the cause of this.

At the time the issue is fixed and available, we let you know.

Thanks for your effort.
Regards
Rudy

All 4 comments

Hi Alexander.

There seems multiple factors that play a role here.

For example, when using a simple servlet which also calls an EJB (similar to AuditEntityServiceBean) the AuditEntity can be persisted, also when the @Convert is present.

So it seems that during the EJB Startup PostConstruct method the CDI system is not yet completely ready in combination when a @Convert is used on an Entity.

Does your usecase require that some information is written to the database at deployment time? Can it be delayed in some way (remark: there is an issue with non-persistent EJB timers on 5.184 which will be solved in the next release)

Another Remark;

The usage of @Convert on @JPA is not supported by the JPA specification. This is the text in section 3.8

The conversion of all basic types is supported except for the following: Id attributes (including the attributes of embedded ids and derived identities), version attributes, relationship attributes, and attributes explicitly annotated as Enumerated or Temporal or designated as such in the XML descriptor.

But is seems to be working on EclipseLink.

Hi there,

you are absolutely right with the @Convert annotation not being allowed on the @Id field. But it does not make a difference even I put the @Convert at a basic attribute. This was an error on my part.
The @PostConstruct does also not matter, I just used it as a convenient way to automatically persist an Entity.

I updated the example project to not use the @PostConstruct and added an simple servlet, which you can call for example like this:
http://localhost:8080/entitylistener-bug-1.0.0-SNAPSHOT/audit

I already analyzed this a little bit further in my previous bug report:

  1. AbstractSession getInjectionManager is called when EntityListeners or AttributeConverters are created.
  2. AbstractSession createInjectionManager fails since it can not find the bean manager. This creates a DisabledInjectionManager, which does no injection on EntityListener creation
  3. EntityListener and InjectionManager instances are reused and therefore injection will never work

Hope this helps

Hi Alexander,

Thank you for the updated version of the reproducer.
I have created an internal issue for our engineers to fix the problem you describe. When JPA Persistence Unit starts deploying, CDI module should be ready so I'm not sure what could be the cause of this.

At the time the issue is fixed and available, we let you know.

Thanks for your effort.
Regards
Rudy

Fixed by #3859

Was this page helpful?
0 / 5 - 0 ratings