У меня есть следующий фрагмент класса, из которого я хотел бы удалить повторяющийся код ведения журнала и переместить его в перехватчик с помощью АОП CDI.

/**
 * Javadoc omitted
 */
public abstract class JpaDao<T extends LongIdentifiable> implements
        GenericDao<T> { 

    @Override
    @Transactional
    public Long persist(T type) throws GeneralPersistenceException {
        if (type == null) {
            throw new GeneralPersistenceException("Can't persist null");
        }

        try {
            entityManager.persist(type);
            return type.getId();
        } catch (PersistenceException e) {
            String message = "Failed to persist an entity";
            logger.error(message, e);
            throw new GeneralPersistenceException(message, e);
        }

    }

    @Override
    @Transactional
    public T merge(T type) throws GeneralPersistenceException {
        if (type == null) {
            throw new GeneralPersistenceException("Can't merge null");
        }

        try {
            T mergedType = entityManager.merge(type);
            return mergedType;
        } catch (PersistenceException e) {
            String message = "Failed to merge an entity";
            logger.error(message, e);
            throw new GeneralPersistenceException(message, e);
        }
    }
}

Обратите внимание на фрагмент кода ниже, который повторяется в методах persist e merge

} catch (PersistenceException e) {
    String message = "Failed to persist an entity";
    logger.error(message, e);
    throw new GeneralPersistenceException(message, e);
}

Код кандидата на замену приведенного выше фрагмента следующий:

} catch (PersistenceException e) {
    throw new GeneralPersistenceException("Failed to persist an entity", e);
}

Другими словами, я бы хотел, чтобы каждый раз, когда выдается GeneralPersistenceException, записывалось сообщение журнала. Мое исключение следующее:

public class GeneralPersistenceException extends Exception {
    private static final long serialVersionUID = -6057737927996676949L;

    public GeneralPersistenceException() {
    }

    public GeneralPersistenceException(String message) {
        super(message);
    }

    public GeneralPersistenceException(String message, Throwable cause) {
        super(message, cause);
    }

    public GeneralPersistenceException(Throwable cause) {
        super(cause);
    }
}

Как видите, Exception имеет только конструкторы. Учитывая этот сценарий, у меня есть следующие вопросы:

  1. Лучшая стратегия для решения этой проблемы в приложении, совместимом с Java EE 7, - использовать АОП с CDI?
  2. Если это АОП, должен ли я перехватить GeneralPersistenceException?
  3. Можно ли перехватить конструкторы GeneralPersistenceException или только методы (которых еще нет)?
  4. Есть ли что-то уже реализованное для этой цели, и я изобретаю велосипед?

Заранее спасибо.

1
Bruno Gasparotto 15 Май 2015 в 19:07
Возможно, вам нужен контроль исключений DeltaSpike? deltaspike.apache.org/documentation/core.html#ExceptionControl
 – 
John Ament
17 Май 2015 в 20:26
1
Это хорошая альтернатива, но это не то, что я ищу. Я действительно хочу обеспечить такую ​​обработку исключений с помощью CDI AOP или чего-то еще, что уже предусмотрено спецификацией Java EE.
 – 
Bruno Gasparotto
18 Май 2015 в 15:58
Ваш вопрос был Is there something already implemented for this purpose and I'm reinventing the wheel? Я просто указал вам на существующее колесо.
 – 
John Ament
18 Май 2015 в 16:30
1
Это был не единственный вопрос, обратите внимание на The best strategy to solve this problem in a Java EE 7 compliant application, is using AOP with CDI?. Но я с тобой не спорю. В любом случае спасибо за ваш совет, но это не совсем то, что я ищу, как сказано выше.
 – 
Bruno Gasparotto
18 Май 2015 в 17:01

1 ответ

Лучший ответ

Вы не можете перехватить исключение, поскольку оно создано с использованием ** new * и не будет управляться CDI. И на практике вы не должны перехватывать таким образом. Решение, которое вы ищете, - это перехватить вызовы в вашей службе, перехватить там ваше исключение и зарегистрировать его.

1
win_wave 23 Май 2015 в 21:56
And in practice you should not intercept in that way. @win_wave, не могли бы вы объяснить почему?
 – 
Bruno Gasparotto
26 Май 2015 в 17:18
Перехватываемые объекты должны управляться CDI, этого не избежать. CDI создает объекты в определенных областях, но экземпляр Exception должен жить только время от его выброса до момента его перехвата. Нет необходимости или использования для управления этим с помощью CDI. Я считаю, что это исключение должно быть как можно более легким.
 – 
win_wave
27 Май 2015 в 21:29
Справедливо. Буду работать над предложенным решением. Спасибо @win_wave.
 – 
Bruno Gasparotto
27 Май 2015 в 21:49