@UniqueConstraint и @Column (unique = true) в аннотации спящего режима
В чем разница между @UniqueConstraint и @Column (unique = true)?
Например:
@Table(
name = "product_serial_group_mask",
uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)
и
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;
Ответы
Ответ 1
Как было сказано ранее, @Column(unique = true)
является ярлыком к UniqueConstraint
, когда это только одно поле.
Из примера, который вы указали, существует огромная разница между ними.
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;
@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;
Этот код означает, что как mask
, так и group
должны быть уникальными, но отдельно. Это означает, что если, например, у вас есть запись с mask.id = 1 и пытается вставить другую запись с mask.id = 1, вы получите ошибка, потому что этот столбец должен иметь уникальные значения. То же самое относится к группе.
С другой стороны,
@Table(
name = "product_serial_group_mask",
uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)
Предполагается, что значения комбинации mask + group должны быть уникальными. Это означает, что у вас может быть, например, запись с mask.id = 1 и group.id = 1, и если вы попытаетесь вставить другую запись с mask.id = 1 и group.id = 2, он будет вставлен успешно, тогда как в первом случае это не будет.
Если вы хотите, чтобы и маска, и группа были уникальными по отдельности и на уровне класса, вам нужно написать код следующим образом:
@Table(
name = "product_serial_group_mask",
uniqueConstraints = {
@UniqueConstraint(columnNames = "mask"),
@UniqueConstraint(columnNames = "group")
}
)
Это имеет тот же эффект, что и первый кодовый блок.
Ответ 2
Из документации Java EE:
public abstract boolean unique
(Необязательно) Является ли свойство уникальным ключом. Это ярлык для UniqueConstraint аннотации на уровне таблицы и полезно, когда уникальный ключ Ограничение - это только одно поле. Это ограничение применяется в дополнение к любому ограничению связанные с отображением первичных ключей и ограничениями, указанными на уровне таблицы.
См. doc
Ответ 3
В дополнение к ответу Боаза....
@UniqueConstraint
позволяет называть ограничение, тогда как @Column(unique = true)
генерирует случайное имя (например, UK_3u5h7y36qqa13y3mauc5xxayq
).
Иногда бывает полезно узнать, с какой таблицей связано ограничение. Например:.
@Table(
name = "product_serial_group_mask",
uniqueConstraints = {
@UniqueConstraint(
columnNames = {"mask", "group"},
name="uk_product_serial_group_mask"
)
}
)
Ответ 4
В дополнение к ответам @Boaz и @vegemite4me....
Внедряя ImplicitNamingStrategy
, вы можете создавать правила автоматического присвоения имен ограничениям. Обратите внимание, что вы добавляете стратегию именования в metadataBuilder
во время инициализации Hibernate:
metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());
Он работает для @UniqueConstraint
, но не для @Column(unique = true)
, который всегда генерирует случайное имя (например, UK_3u5h7y36qqa13y3mauc5xxayq).
Для решения этой проблемы существует отчет об ошибке, поэтому , если можно, пожалуйста, проголосуйте там, чтобы это реализовано. Здесь:
https://hibernate.atlassian.net/browse/HHH-11586
Спасибо.