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), с классами, которые вы предоставляете в качестве примера, и мы можем попытаться это исправить.
Чтобы обойти это, попробуйте внедрить событие в конкретный подкласс и передать его в качестве аргумента или использовать метод доступа, чтобы получить его в абстрактном суперклассе.