Пользовательская аннотация Hibernate не срабатывает для поля, отличного от @Id, в приложении Spring BootJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Пользовательская аннотация Hibernate не срабатывает для поля, отличного от @Id, в приложении Spring Boot

Сообщение Anonymous »

Чего я хочу достичь
Я пытаюсь автоматически сгенерировать уникальный номер FlightNumber для поля в сущности FlightInstance перед его сохранением в базе данных. FlightNumber не является первичным ключом (@Id) и должен генерироваться с использованием пользовательской логики последовательности с префиксом.
Что я уже сделал
  • < li>Создана специальная аннотация для обозначения поля FlightNumber:

Код: Выделить всё

@IdGeneratorType(value = FlightNumberSequenceGenerator.class)
@Retention(RUNTIME)
@Target({METHOD,FIELD})
public @interface FlightNumberSequence {

String name();
String prefix() default "FWF-";
int startWith() default 1;
int incrementBy() default 1;
}
  • Реализован собственный генератор:

Код: Выделить всё

public class FlightNumberSequenceGenerator implements BeforeExecutionGenerator {

private final String prefix;
private final int incrementBy;

public FlightNumberSequenceGenerator(FlightNumberSequence config) {
System.out.println("Hello from FlightNumberSequenceGenerator");
this.prefix = config.prefix();
this.incrementBy = config.incrementBy();
}

@Override
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
System.out.println("Hello from FlightNumberSequenceGenerator");
return session.doReturningWork(connection -> {
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("SELECT next_val FROM flight_number_sequence FOR UPDATE");
if (resultSet.next()) {
int nextVal = resultSet.getInt("next_val");
statement.executeUpdate("UPDATE flight_number_sequence SET next_val = " + (nextVal + incrementBy));
return prefix + nextVal;
} else {
throw new IdentifierGenerationException("Unable to fetch the next sequence value.");
}
} catch (Exception e) {
throw new IdentifierGenerationException("Error generating flight number.", e);
}
});
}

@Override
public EnumSet getEventTypes() {
return EventTypeSets.INSERT_ONLY;
}
}
  • Добавил примечание к полю FlightNumber в моем объекте FlightInstance:

    Код: Выделить всё

    @Entity
    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    @NoArgsConstructor
    public class FlightInstance extends FlyWellModel {
    
    private boolean isFullyBooked;
    @Column(unique = true)
    @FlightNumberSequence(name = "flight_number_sequence", startWith = 1000, incrementBy = 3)
    private String flightNumber;
    private LocalDateTime departureTime;
    private LocalDateTime arrivalTime;
    private int baggageAllowance;
    @OneToOne
    private AirCraft airCraft;
    @OneToOne
    @ToString.Exclude
    private Flight flight;
    @Enumerated(STRING)
    private FlightStatus status;
    @OneToMany()
    @ToString.Exclude
    private List flightSeat;
    }
    
  • Моя базовая модель (FlyWellModel) включает поле @Id и другие общие атрибуты:

Код: Выделить всё

@Getter
@Setter
@SuperBuilder
@EntityListeners(value = {AuditingEntityListener.class})
@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
public class FlyWellModel {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
private String publicId;
@CreatedDate
LocalDateTime createdDate;
@LastModifiedDate
LocalDateTime lastModifiedDate;
@CreatedBy
@Builder.Default
String createdBy = "SYSTEM";

String createdByRole;
@LastModifiedBy
String lastModifiedBy;

@PrePersist
private void generatePublicId(){
publicId = UUID.randomUUID().toString();
}
}
Проблема, с которой я столкнулся
Пользовательский генератор FlightNumberSequenceGenerator не запускается. Я добавил операторы печати в методgenerate(), но подтвердил, что он не вызывается. Поле FlightNumber остается нулевым после сохранения объекта в базе данных.
Что я подозреваю
Поскольку поле FlightNumber имеет значение а не поле @Id, Hibernate может не обрабатывать его генератор автоматически.
Моя пользовательская аннотация может потребовать дополнительной настройки для подключения к жизненному циклу объекта.
Что Я хочу знать
Как правильно настроить пользовательскую аннотацию для автоматического запуска логики генератора перед сохранением объекта?
Существует ли ограничение на использование пользовательских аннотаций или пользовательских генераторов для полей, которые не являются первичными ключами? Чего мне не хватает в настройке, чтобы это работало?

Подробнее здесь: https://stackoverflow.com/questions/793 ... -boot-appl
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»