Несколько вопросов по EntityChangedEvent Listener

Добрый день.

Не могли бы прояснить ситуацию относительно слушателей в платформе версии 7? Вижу, что студия позволяет создать только EntityChangedEvent Listener (двух типов).

  • Правильно я понимаю, что в новой парадигме эти два типа слушателей заменяют всю рассыпуху слушателей, которые были в предыдущей версии (как transactional, так и нет)?
  • Можно ли располагать слушатели в одном классе, как в примере в документации? В студии не предусмотрено такое поведение.
  • Мешают ли старые слушатели новым? Вопрос потому что столкнулся с некоторыми странностями.
  • Корректно ли повесить слушатели на предка (общая логика) и на его потомков? Или лучше в только предке и уже внутри разбираться, что за потомок?
2 симпатии

Добрый день,

студия позволяет создать только

В студии не предусмотрено такое поведение.

Приоритетной является, конечно, документация платформы (и детали реализации в github-тикетах). Студия может отставать от платформы по поддержке некоторых новых её возможностей.

Кроме того, Студия ориентирована на то, чтобы быть дружелюбной для новичков enterprise Java программирования. Поэтому многие возможности по генерации Java / Spring / CUBA контента будут генерировать более шаблонный и ограниченный код, нежели может написать опытный Java / Spring / JPA / CUBA разработчик.

Александр, можно ли раскрыть ответы на 1, 3, 4 вопросы по существу. Не хотелось бы собирать все грабли.

  • Правильно я понимаю, что в новой парадигме эти два типа слушателей заменяют всю рассыпуху слушателей, которые были в предыдущей версии (как transactional, так и нет)?

Да, EntityChangedEvent является теперь рекомендуемым способом, вместо старых Before/After Insert/Update/Delete Listeners.

BeforeCommitTransactionListener и AfterCompleteTransactionListener в список “старых” попадают?

Да, можно.

Нет, не должны мешать. Если у вас проявляется какое-либо неочевидное поведение, попробуйте пожалуйста смоделировать его на тестовом проекте и предоставить нам.

Если речь идет об иерархиях классов сущностей, то нет, вы можете повесить слушателя только на конкретный класс сущности. Базовый класс слушать нельзя.

1 симпатия

Константин, спасибо за ответы.
Извиняюсь, но я задам еще.

Вы не рекомендуете, или в принципе нельзя?
Просто у меня получается:

Сведения
@Component("unitChangedListener")
public class UnitChangedListener {
    @EventListener
    private void beforeCommit(EntityChangedEvent<? extends Unit, UUID> event) {
        ...
    }
}
  1. Это чем-то чревато?
  2. Рекомендуете ли несколькими слушателями слушать один класс (разбить на логические/функциональные части)? Или лучше в одном?
  3. @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) - пока исполняется держит UI, но при этом не бросает в UI исключения, это нормально?
  4. Не могли бы вы дать общую рекомендацию, когда правильным было бы использовать слушатель внутри транзакции или после ее завершения, исходя из вашего опыта. На мой взгляд, изменения связанных сущностей “логично” выполнять после завершения транзакции, но пример в документации и п.3 несколько смущают.

1 - А что так можно было? Я не знал, честно.

2 - ничего не могу посоветовать. Мне кажется это все дело вкуса.

3 - да, это нормально. Выполнение синхронное, поэтому UI ждет. Исключение логгируется но не выбрасывается в вызывающий код, это контракт Spring TransactionSynchronization. Мы упомянем это в документации на листенеры, спасибо что обратили внимание.

4 - на мой взгляд связанные сущности надо обновлять в одной транзакции, чтобы сохранить консистентность в случае ошибок. После завершения транзакции обычно выполняют действия типа отсылки email или какие-то иные оповещения. Но опять же все определяется логикой вашего приложения.