4.4.4.6. Entity Listeners

Entity Listeners предназначены для реакции на события жизненного цикла экземпляров сущностей на уровне Middleware.

Слушатель представляет собой класс, реализующий один или несколько интерфейсов пакета com.haulmont.cuba.core.listener. Слушатель будет реагировать на события типов, соответствующих реализуемым интерфейсам.

BeforeDetachEntityListener

Метод onBeforeDetach() вызывается перед отделением объекта от EntityManager при коммите транзакции.

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

BeforeAttachEntityListener

Метод onBeforeAttach() вызывается перед введением объекта в персистентный контекст при выполнении операции EntityManager.merge().

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

BeforeInsertEntityListener

Метод onBeforeInsert() вызывается перед выполнением вставки записи в БД. В данном методе возможны любые операции с текущим EntityManager.

AfterInsertEntityListener

Метод onAfterInsert() вызывается после выполнения вставки записи в БД, но до коммита транзакции. В данном методе нельзя модифицировать текущий персистентный контекст, однако можно производить изменения в БД с помощью QueryRunner.

BeforeUpdateEntityListener

Метод onBeforeUpdate() вызывается перед изменением записи в БД. В данном методе возможны любые операции с текущим EntityManager.

AfterUpdateEntityListener

Метод onAfterUpdate() вызывается после изменения записи в БД, но до коммита транзакции. В данном методе нельзя модифицировать текущий персистентный контекст, однако можно производить изменения в БД с помощью QueryRunner.

BeforeDeleteEntityListener

Метод onBeforeDelete() вызывается перед удалением записи из БД (или в случае мягкого удаления - перед изменением записи). В данном методе возможны любые операции с текущим EntityManager.

AfterDeleteEntityListener

Метод onAfterDelete() вызывается после удаления записи из БД (или в случае мягкого удаления - после изменения записи), но до коммита транзакции. В данном методе нельзя модифицировать текущий персистентный контекст, однако можно производить изменения в БД с помощью QueryRunner.

Entity Listener может быть как обычным классом Java, так и управляемым бином. В последнем случае в нем можно использовать инжекцию:

@Component("cuba_MyEntityListener")
public class MyEntityListener implements
        BeforeInsertEntityListener<MyEntity>,
        BeforeUpdateEntityListener<MyEntity> {

    @Inject
    protected Persistence persistence;

    @Override
    public void onBeforeInsert(MyEntity entity) {
        EntityManager em = persistence.getEntityManager();
        ...
    }

    @Override
    public void onBeforeUpdate(MyEntity entity) {
        EntityManager em = persistence.getEntityManager();
        ...
    }
}

Entity Listener может быть задан двумя способами:

  • Статически - имена классов слушателей, или, если слушатель является бином, имена бинов, указываются в аннотации @Listeners на классе сущности:

    @Entity(...)
    @Table(...)
    @Listeners("cuba_MyEntityListener")
    public class MyEntity extends StandardEntity {
        ...
    }
  • Динамически - класс сущности и класс слушателя, или, если слушатель является бином, имя бина, передаются в метод addListener() бина EntityListenerManager. Пример динамического добавления слушателя рассматривается в разделе рецептов разработки: Выполнение кода на старте приложения.

Для всех экземпляров некоторого класса сущности извлекается из контекста Spring или создается и кэшируется один экземпляр слушателя определенного типа, поэтому слушатель не должен иметь состояния.

Если для сущности объявлены несколько слушателей одного типа (например, аннотациями класса сущности и его предков, плюс динамически), то их вызов будет выполняться в следующем порядке:

  1. Для каждого предка, начиная с самого дальнего, вызываются его динамически добавленные слушатели, затем статически назначенные.

  2. После всех предков вызываются динамически добавленные слушатели данного класса, затем статически назначенные.