Автоинкремент id при создании сущности во внешней базе (как вмешаться в скрытую логику)

Здравствуйте!

Мы переписываем унаследованное приложение, и нужно сохранить данные.
Интересны ваши рекомендации к самому подходу…

ETL пакетом грузим все имеющиеся в старой системе экземпляры сущностей с их имеющимися идентификаторами (для сохранения связей с другими объектами системы).
Создаем сущность во внешней базе путем генерации из таблицы SQL Server:

package ru.roe.infocenter.entity;
import com.haulmont.chile.core.annotations.NamePattern;
import com.haulmont.cuba.core.entity.BaseIntegerIdEntity;
import com.haulmont.cuba.core.global.DesignSupport;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@DesignSupport("{'imported':true}")
@NamePattern("%s|name")
@Table(name = "cl_link_role")
@Entity(name = "infocenter_ClLinkRole")
public class ClLinkRole extends BaseIntegerIdEntity {

    private static final long serialVersionUID = 8724449190756532183L;

    @NotNull(message = "{msg://infocenter_ClLinkRole.name.validation.NotNull}")
    @Column(name = "name", nullable = false)
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Сгенерированный Editor при создании нового экземпляра сущности естественно подставляет 1. Нам же нужно немного изменить эту часть логики (id из имеющихся в базе + 1). Как это правильно сделать?

Попытка в сущности сделать: Event Listeners > Create EntityChangeEvent listener приводит к ошибке “Entity does not have UUID”…

Здравствуйте, Андрей!

Для слушателя EntityChangedEvent нет необходимости иметь UUID в сущности, это ошибка студии.

Однако данный тип событий не лучшим образом подходит для изменения сущности перед сохранением, так как в нем не содержится экземпляра сущности. Эффективнее будет воспользоваться механизмом Entity Listeners, а именно методом onBeforeInsert(). Либо воспользоваться аннотацией @PrePersist из Lifecycle Callbacks сущности.

Также вы можете присваивать подходящий id сущности не на этапе сохранения, а в редакторе на этапе инициализации новой сущности - воспользовавшись InitEntityEvent.

С уважением,
Сергей

1 симпатия

Сергей, спасибо за исчерпывающий ответ!
Надеюсь, со временем создание различных слушателей для сущностей будет поддержана в дизайнере сущностей…

Данная проблема (с созданием EntityChangedEventListener для сущности с типом id, отличным от UUID) уже исправлена в Studio 13, которая на текущий момент доступна в бета-версии.

Сергей, я тут добавлю свои пять копеек.

Кажется, что Андрей имел в виду, что было бы здорово добавить в студию возможность создания Entity Listeners.

Сейчас у меня складывается впечатление, что это некий устаревший механизм, поскольку возможность создания этих слушателей отсутствует в студии.
Ну и было бы вдвойне здорово, если бы вы дали рекомендации (в документации) в каких случаях каким слушателям отдать предпочтение (EntityChangedEvent или EntityListener).

2 симпатии

Именно, Михаил. Отлично сформулировали )

Добрый день!

Для инициализации атрибутов новых экземпляров лучше использовать EntityPersistingEvent, появившийся в CUBA 7.1.

А рекомендация простая: всегда использовать EntityChangedEvent/EntityPersistingEvent, а entity listeners - только когда вы абсолютно уверены что вам это нужно. Именно поэтому их нет в интерфейсе Студии.

И пожалуйста сообщите нам, если встретите use case в котором EntityChangedEvent/EntityPersistingEvent неприменимы, мы подумаем как их доработать.

С уважением,
Константин

1 симпатия