Поскольку ваша функция entityClass не вызывается, она не заполняет ваше поле entityClass, поэтому при вызове она всегда будет иметь значение null.
Вы можете использовать аналогичный подход, избегая необходимости в точке инъекции, используя метод получения, который использует параметризованный тип. Ваш код изменится на:
@Dependent
public abstract class EntityService<T, ID> {
@Inject
private GenericEntityService<T, ID> entityService;
private Class<T> entityClass;
public synchronized Class<T> getEntityClass() {
if (entityClass == null) {
entityClass = inferEntityClass(getClass());
}
return entityClass;
}
private Class<?> inferEntityClass(Class<?> clazz) {
// This code should be safer
ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
return (Class<T>) parameterizedType.getActualTypeArguments()[0];
}
public T find(ID id) {
return entityService.find(getEntityClass(), id);
}
// ...
}
Кстати, не связанное с этим: я не понял причины, по которой вы должны создать еще один уровень bean-компонентов вместо вызова EntityManager непосредственно из EntityService. Обратите внимание, что некоторые функции, оправдывающие эту архитектуру, такие как управление транзакциями, уже присутствуют в CDI.