CDI events and generics

I try to post events and do this in general. I mean, create one abstract DAO base class with a common type and fire the event from its method. This should work for all descendants. This works if I define the exact type, but not if I use generics. What I mean:

AbstractDAO (with generics - does not fire an event):

public abstract class AbstractDAO<T extends Persistable> implements Serializable { @Inject @PostSaveEvent Event<T> postSaveEvent; public T saveOrUpdate(T object) throws DatabaseException { T obj = em.merge(object); postSaveEvent.fire(obj); } } 

AbstractDAO (no generics, just a cool class - the event fires):

 public abstract class AbstractDAO<T extends Persistable> implements Serializable { @Inject @PostSaveEvent Event<Polis> postSaveEvent; public T saveOrUpdate(T object) throws DatabaseException { T obj = em.merge(object); postSaveEvent.fire((Polis)obj); } } 

The PolisDAO class, which extends AbstractDAO and defines a generic type:

 @Stateless @Named @PolisType public class PolisDAO extends AbstractDAO<Polis> { // some methods (saveOrUpdate is not overriden!) } 

My observer class:

 @Stateless @Named public class ProlongationService { public void attachProlongationToPolisOnSave(@Observes @PostSaveEvent Polis polis) throws DatabaseException { // ... DO smth with polis object. This is NOT called in the first case and called in the second } 

This is very strange for me, since the "fire ()" method for a CDI event should determine the type of event at runtime, and not at compile time or deployment ... When I debug, I see that

 postSaveEvent.fire(obj); 

from the first sample works exactly with the Polis object. However, not a single event was fired ...

Update. I tried the base general class but no luck:

 @Inject @PostSaveEvent Event<Persistable> postSaveEvent; 

Thanks.

+4
source share
1 answer

This should theoretically work, but in practice, checking the type of universal objects at runtime using Java Reflection is sometimes not possible. This is due to type erasure. The IIRC type of a particular subclass is not erased, so it can be reconnected, but I assume that the implementation is not doing it right now.

Note this as an error in the http://issues.jboss.org/browse/WELD questionnaire (if you use Weld), with the classes that you provide as an example and we can try to fix it.

To work around this, try introducing the event into a specific subclass and passing it as an argument or using the accessor method to get it in an abstract superclass.

+4
source

Source: https://habr.com/ru/post/1392341/


All Articles