it-swarm.com.ru

@Column (unique = true) создает WARN o.h.engine.jdbc.spi.SqlExceptionHelper: Код предупреждения SQL: 0, SQLState: 00000

В проекте с Spring Boot 2.0.0.RELEASE , когда я запускаю приложение в первый раз, когда создаются таблицы базы данных, я получаю следующее предупреждение:

Hibernate: alter table if exists bpermission drop constraint if exists UK_qhp5om4s0bcb6j0j8pgcwitke
2018-03-14 11:32:03.833  WARN 15999 --- [  restartedMain] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: 0, SQLState: 00000
2018-03-14 11:32:03.833  WARN 15999 --- [  restartedMain] o.h.engine.jdbc.spi.SqlExceptionHelper   : constraint "uk_qhp5om4s0bcb6j0j8pgcwitke" of relation "bpermission" does not exist, skipping

Обратите внимание на имя ограничения -> uk_qhp5om4s0bcb6j0j8pgcwitke

... и ниже я вижу, что это регистрируется:

Hibernate: alter table if exists bpermission add constraint UK_qhp5om4s0bcb6j0j8pgcwitke unique (label)
Hibernate: alter table if exists bpermission drop constraint if exists UK_ow4uw3orjjykeq869spvqtv6u

Из предыдущего сообщения мы видим, что Hibernate добавляет ограничение UK_qhp5om4s0bcb6j0j8pgcwitke, такое же, как показано в предупреждении, но первая буква заглавная. Это связано с ограничением unique в свойстве label (см. Класс ниже).

(Возможные) вовлеченные объекты в получении этого предупреждения:

BPermission

@Data
@NoArgsConstructor(force = true)
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = true, exclude = "roles")
@ToString(callSuper = true, exclude = "roles")
@Entity
public class BPermission extends GmsEntity {

    @NotNull()
    @NotBlank()
    @Size(max = 255)
    @Pattern(regexp = "someDefinedRegexp")
    @Column(unique = true, nullable = false, length = 255)
    private final String name;

    @NotNull()
    @NotBlank()
    @Size(max = 255)
    @Column(unique = true, nullable = false, length = 255)
    private final String label;

    @ManyToMany(mappedBy = "permissions")
    private Set<BRole> roles;
}

BPermission относится (в случае, если эта информация помогает каким-либо образом) к 

BRole

@Data
@NoArgsConstructor(force = true)
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = true, exclude = "permissions")
@ToString(callSuper = true, exclude = {"description", "permissions"})
@Entity
public class BRole extends GmsEntity{

    @NotNull()
    @NotBlank()
    @Size(max = 255)
    @Pattern(regexp = "someDefinedRegexp"))
    @Column(unique = true, nullable = false, length = 255)
    private final String label;

    @Size(max = 10485760)
    @Column(length = 10485760)
    private String description;

    private Boolean enabled = false;

    @ManyToMany
    @JoinTable(
            name = "brole_bpermission",
            joinColumns = @JoinColumn(name = "brole_id"),
            inverseJoinColumns = @JoinColumn(name = "bpermission_id")
    )
    private Set<BPermission> permissions;

    public void addPermission(BPermission... p) {
        // code for adding permissions
    }

    public void removePermission(BPermission... p) {
        // code for removing permissions
    }

    public void removeAllPermissions() {
        // code for removing permissions
    }

Они отображаются в базу данных PostgreSQL9.5.11 следующим образом:

enter image description here

Связанные конфигурации пружины:

spring.datasource.url = jdbc:postgresql://127.0.0.1/mydbname
spring.datasource.username = postgres
spring.datasource.password = postgres
spring.datasource.driver-class-name = org.postgresql.Driver
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation = true
spring.jpa.open-in-view = false

Я получаю упомянутое предупреждающее сообщение для всех объектов со свойствами, помеченными @Column(unique = true)

Q:

  • Почему выдается это предупреждение? Может быть ... ошибка?
  • Как я могу избавиться от этого?

Конечно, иногда предупреждение совсем не плохо, но я чувствую, что это либо не нужно, либо указывает на то, что «что-то должно быть сделано иначе», несмотря на то, что SQLCode 0000 означает «success_completion».

PS: я использую Lombok .

10
lealceldeiro

Spring Boot 2.0 (Hibernate 5?), Очевидно, использует DROP_RECREATE_QUIETLY в качестве уникальную стратегию обновления ограничений которая на самом деле неверна в качестве опции по умолчанию, потому что просто то, что происходит при каждом запуске приложения, - это удаление уникального индекса и его повторное создание. Если вы работаете с базами данных с некоторыми (большим количеством?) Данными, я могу представить, насколько медленным будет запуск всего с этой опцией.

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

Чтобы отключить это, вам нужно переключить стратегию обратно на RECREATE_QUIETLY со следующими параметрами:

# for plain hibernate
hibernate.schema_update.unique_constraint_strategy=RECREATE_QUIETLY

# for spring data
spring.jpa.properties.hibernate.schema_update.unique_constraint_strategy=RECREATE_QUIETLY
1
Łukasz Frankowski

Это похоже на ошибку.

Я бы порекомендовал вам создать схему с помощью высокоуровневых инструментов миграции, таких как flywaydb, и позволить hibernate проверять только сгенерированную схему. Он интегрирован в подпружиненную загрузку и его очень легко настроить, см. документацию и примеры .

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

Обычно автоматическая генерация схемы используется только в процессе разработки, но не в производстве. Вы можете найти более подробную информацию о том, почему это так важно здесь .

Имея такую ​​настройку, вы можете позволить hibernate генерировать схему только в режиме разработки, но flighway возьмет на себя ответственность за остальные случаи.

3
Oleksandr Shpota