Что произойдет, если я использую ограничение на ПК? - PullRequest
0 голосов
/ 16 мая 2019

Что произойдет, если у меня есть PK и я наложу на него ограничение. Я знаю, что когда я пытаюсь записать в БД одну и ту же сущность, она перезапишет ее, а не вызовет конфликт из-за ограничения. Вопрос почему? Он перезаписывает его, потому что он написан с помощью спящих - пружинных данных jpa - и метод jpaRepository.save (). Таким образом, он перезаписывает объект, если у него одинаковый PK и все остальные столбцы одинаковые.

Это происходит даже в следующем случае: У меня есть ограничение на 3 столбца VARCHAR: (имя, версия, тип) У меня есть PK, сформированный добавлением 3 VARCHARS вместе: name_version_type

это то, что происходит в файле sql с пружиной и пролетом при создании схемы:

CREATE TABLE package
(
   id surrogate_id PRIMARY KEY,
   CONSTRAINT uq_package_name_version_type UNIQUE(surrogate_id),
   name VARCHAR NOT NULL,
   version VARCHAR NOT NULL,
   type VARCHAR NOT NULL
)
;

это то, что происходит в Java с Hibernate:

@Table(name = PackageEntity.TABLE_NAME, uniqueConstraints = {
    @UniqueConstraint(columnNames = {"package"}, name = ConstraintName.SURROGATE_ID)})

столбцы:

@NotNull
private String name;

@NotNull
private String version;

@NotNull
private String type;

@Id
@Column(name = "surrogate_id")
private String surrogateId;

и как создается суррогатный идентификатор:

public static final String hash(String name, String version, String type)
{
    return new StringBuilder().append(name)
                              .append("_").append(version)
                              .append("_").append(type)
                              .toString();
}

Я ожидаю, что он видит тот же PK и пытается перезаписать объект, но я также ожидаю остановить транзакцию, потому что он видит конфликт в столбце 3. Так не бывает Это только считает ПК. Почему?

Ответы [ 2 ]

1 голос
/ 16 мая 2019

Весной JpaRepository по умолчанию операция save работает следующим образом:

  1. , если у объекта не установлен первичный ключ (поле с аннотацией @Id) - новая записьв созданном в базе данных с использованием INSERT оператора SQL
  2. , если у сущности есть первичный ключ - существующая запись модифицируется с использованием UPDATE оператора SQL.

Так что в вашем случаеSpring считает, что вы обновляете существующую сущность, и вставка не происходит, поэтому не возникает конфликта.Вот почему ограничение бесполезно.

Чтобы преодолеть это, вы можете реализовать интерфейс Persistable и метод isNew специально для того, чтобы Spring узнал, что вы вставляете новую сущность.В этом случае пружина будет вставлять, а не обновлять.

1 голос
/ 16 мая 2019

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

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

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