Hazırda bekletme ek açıklamasında @UniqueConstraint ve @Column (benzersiz = true)


105

@UniqueConstraint ve @Column (unique = true) arasındaki fark nedir ?

Örneğin:

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

Ve

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

2
Not: Hibernate 5.4 ile, eklediğimde unique=true, indeks şema otomatik güncelleyici tarafından eklenmedi. @UniqueConstraintgörünmesini sağladı. Bir hata olabilir.
Ondra Žižka

Yanıtlar:


148

Daha önce de söylendiği gibi, yalnızca tek bir alan olduğunda @Column(unique = true)kısayol UniqueConstraint.

Verdiğiniz örnekten, ikisi arasında büyük bir fark var.

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

Bu kod hem ima maskve groupayrı ayrı benzersiz olması lazım, ama. Bu, örneğin mask.id = 1 olan bir kaydınız varsa ve mask.id = 1 ile başka bir kayıt eklemeye çalışırsanız , bir hata alacağınız anlamına gelir, çünkü bu sütunun benzersiz değerleri olmalıdır. Aynı şey grup için de geçerlidir.

Diğer yandan,

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

Birleştirilmiş maske + grup değerlerinin benzersiz olması gerektiğini ifade eder. Bu, örneğin mask.id = 1 ve group.id = 1 olan bir kayda sahip olabileceğiniz anlamına gelir ve mask.id = 1 ve group.id = 2 ile başka bir kayıt eklemeye çalışırsanız, bu kayıt eklenecektir başarılı bir şekilde, oysa ilk durumda olmaz.

Hem maskenin hem de grubun ayrı ayrı benzersiz olmasını ve buna sınıf düzeyinde olmasını istiyorsanız, kodu aşağıdaki gibi yazmanız gerekir:

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

Bu, ilk kod bloğu ile aynı etkiye sahiptir.


Benzersiz kısıtlama oluşturulduktan sonra, bunu sorgulamak için JPA Depomdaki kısıtlamaya ada göre başvurabilir miyim?
jDub9

@ jDub9 Bir indeksi sorgulayamazsınız. Maske ve grup sütunlarını tek bir sorguda sorgulayabilirsiniz ve daha hızlı işlem için bu dizini kullanır (eğer şanslıysanız), ancak bir dizini kolayca sorgulayamazsınız.
Dalibor Filus

Bu sütun adlarının veritabanındaki gerçek adlar olması gerektiğine dikkat edin. Varsayılan adlandırma stratejisi kullanıyorsanız mask_idve olmalıdır group_id.
nitro

27

Java EE belgelerinden:

public abstract boolean unique

(İsteğe bağlı) Özelliğin benzersiz bir anahtar olup olmadığı. Bu, tablo düzeyinde UniqueConstraint ek açıklaması için bir kısayoldur ve benzersiz anahtar kısıtlaması yalnızca tek bir alan olduğunda yararlıdır. Bu kısıtlama, birincil anahtar eşlemesinin gerektirdiği tüm kısıtlamalara ve tablo düzeyinde belirtilen kısıtlamalara ek olarak geçerlidir.

Belgeye bakın


bu yüzden bu kodu kullandığımda: @Column (benzersiz = doğru) @ManyToOne (isteğe bağlı = false, fetch = FetchType.EAGER) özel ProductSerialMask maskesi; @Column (benzersiz = doğru) @ManyToOne (isteğe bağlı = false, fetch = FetchType.EAGER) özel Grup grubu; İki dizinim var, ancak başka bir şekilde kullandığımda, iki sütunun birleştiği bir dizinim var?
navid_gh

22

Boaz'ın cevabına ek olarak ....

@UniqueConstraintEğer olanak kısıtlamayı isim olurken, @Column(unique = true)rasgele bir isim (örneğin üretir UK_3u5h7y36qqa13y3mauc5xxayq).

Bazen bir kısıtlamanın hangi tabloyla ilişkilendirildiğini bilmek yardımcı olabilir. Örneğin:

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

5

@ Boaz ve @ vegemite4me yanıtlarına ek olarak ....

Uygulayarak ImplicitNamingStrategyotomatik kısıtlamaları adlandırma kurallarını oluşturabilir. Adlandırma stratejinizi metadataBuilderHazırda Bekletme'nin başlatılması sırasında eklediğinizi unutmayın :

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

Her zaman rastgele bir ad üreten @UniqueConstraintiçin çalışır , ancak bunun için @Column(unique = true)çalışmaz (örn. UK_3u5h7y36qqa13y3mauc5xxayq).

Bu sorunu çözmek için bir hata raporu var, bu yüzden eğer yapabiliyorsanız, bunun uygulanması için lütfen orada oy verin. Burada: https://hibernate.atlassian.net/browse/HHH-11586

Teşekkürler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.