CDI события и дженерики

Я пытаюсь отправить события и сделать это в общем. Я имею в виду - создайте один абстрактный базовый класс DAO с универсальным типом и запустите событие из его метода. Это должно работать для всех потомков. Это работает, если я определяю точный тип, но не - если я использую дженерики. Что я имею в виду:

AbstractDAO (с генериками - не запускает событие):

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 (без обобщений, просто приведение классов - запускает событие):

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);
   }
}

Класс PolisDAO, который расширяет AbstractDAO и определяет универсальный тип:

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

Мой класс наблюдателей:

@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
    }

Это очень странно для меня, так как метод "fire ()" для события CDI должен определять тип события во время выполнения, а не во время компиляции или развертывания... Когда я отлаживаю, я вижу, что

postSaveEvent.fire(obj);

из первого образца действует именно с полисной сущностью. Но, тем не менее, ни одно событие не произошло...

Upd. Я попробовал базовый базовый класс, но не повезло:

@Inject @PostSaveEvent Event<Persistable> postSaveEvent;

Благодарю.

1 ответ

Решение

Теоретически это должно работать, однако на практике проверка типа универсальных объектов во время выполнения с помощью Java Reflection иногда невозможна. Это связано с стиранием типа. IIRC тип конкретного подкласса не стирается, поэтому должна быть возможность восстановить это, но я полагаю, что реализация не делает этого прямо сейчас.

Отправьте это как ошибку в http://issues.jboss.org/browse/WELD средство отслеживания ошибок (если вы используете Weld), с классами, которые вы предоставляете в качестве примера, и мы можем попытаться это исправить.

Чтобы обойти это, попробуйте внедрить событие в конкретный подкласс и передать его в качестве аргумента или использовать метод доступа, чтобы получить его в абстрактном суперклассе.

Другие вопросы по тегам