@UniqueConstraint и @Column (unique = true) в аннотации hibernate

в чем разница между @ограничение 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;

4 ответов


как уже было сказано,@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 должны быть уникальными, но отдельно. Это означает, что если, например, у вас есть запись смаска.id = 1 и пытается вставить другую запись с маска.id = 1, вы получите ошибку, потому что этот столбец должен имеют уникальные значения. То же она относится к группе.

С другой стороны,

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

подразумевает, что значения mask + group должны быть уникальными. Это означает, что вы можете иметь, например, запись смаска.id = 1 и группа.id = 1, и если вы попытаетесь вставить другую запись с маска.id = 1 и группа.id = 2, он будет вставлен успешно, тогда как в первом случае это не будет.

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

@Table(
        name = "product_serial_group_mask",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = "mask"),
                @UniqueConstraint(columnNames = "group")
        }
)

это имеет тот же эффект, что и первый блок кода.


из документации Java EE:

public abstract boolean unique

(необязательно) является ли свойство уникальным ключом. Это ярлык для Uniqueconstraint аннотация на уровне таблицы и полезна, когда уникальный ключ ограничение только одно поле. Это ограничение применяется в дополнение к любому ограничению влечет за собой сопоставление первичных ключей и ограничений, указанных на уровне таблицы.

посмотреть doc


в дополнение к ответу Боаза ....

@UniqueConstraint позволяет имя ограничение, а @Column(unique = true) генерирует случайное имя (например,UK_3u5h7y36qqa13y3mauc5xxayq).

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

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {
      @UniqueConstraint(
          columnNames = {"mask", "group"},
          name="uk_product_serial_group_mask"
      )
   }
)

в дополнение к ответам @Boaz и @vegemite4me....

введя ImplicitNamingStrategy вы можете создать правила для автоматического именования ограничений. Примечание добавить вашу стратегию именования к metadataBuilder во время инициализации Hibernate:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

Он работает @UniqueConstraint, а не @Column(unique = true), который всегда генерирует случайное имя (например, UK_3u5h7y36qqa13y3mauc5xxayq).

есть отчет об ошибке, чтобы решить эту проблему, так если вы можете, пожалуйста, голосуйте там это должно быть реализовано. здесь: https://hibernate.atlassian.net/browse/HHH-11586

спасибо.