2013-03-12 17 views
48

Jaka jest różnica między @UniqueConstraint i @Column (unikatowy = true)?@UniqueConstraint i @Column (unikatowy = true) w hibernacji adnotacji

Na przykład:

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

I

@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

Uwaga: W przypadku hibernacji 5.4, gdy dodałem wartość "unikalny = true", indeks nie został dodany przez auto-aktualizator schematu. Na ekranie wyświetlił się '@ UniqueConstraint'. To może być błąd. –

Odpowiedz

53

Jak wspomniano wcześniej, @Column(unique = true) jest skrótem do UniqueConstraint kiedy jest tylko jedno pole.

Z podanego przykładu wynika, że ​​istnieje ogromna różnica między nimi.

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

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

Ten kod oznacza, że ​​zarówno mask i group muszą być unikatowe, ale oddzielnie. Oznacza to, że jeśli na przykład masz rekord z mask.id = 1 i spróbujesz wstawić kolejny rekord z mask.id = 1, otrzymasz błąd, ponieważ kolumna powinna mieć unikalne wartości . To samo dotyczy grupy.

Z drugiej strony,

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

wynika, że ​​wartości maski + Grupa Połączone powinny być niepowtarzalne. Oznacza to, że można mieć, na przykład, zapis z mask.id = 1 i group.id = 1, a jeśli staramy się włożyć kolejną płytę z mask.id = 1 i group.id = 2, zostanie wstawiony pomyślnie, podczas gdy w pierwszym przypadku nie.

Jeśli chcesz mieć zarówno maskę i grupę być unikalne osobno i że na poziomie klasy, trzeba by napisać kod w następujący sposób:

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

ten ma takie samo działanie jak pierwszy blok kodu.

+0

Po utworzeniu ograniczenia unikalności, czy mogę odwołać się do ograniczenia po nazwie w moim repozytorium JPA, aby zapytać o to? – jDub9

25

Z dokumentacji Java EE:

public abstract boolean unique 

(opcjonalnie), czy właściwość jest unikalnym kluczem. Jest to skrót do adnotacji UniqueConstraint na poziomie tabeli i jest przydatny, gdy ograniczenie pojedynczego klucza jest tylko pojedynczym polem. Ograniczenie to stosuje się dodatkowo do każdego ograniczenia powodowanego przez mapowanie klucza podstawowego i do ograniczeń określonych na poziomie tabeli.

Zobacz doc

+0

, więc kiedy używam tego kodu: @Column (unique = true) @ManyToOne (opcjonalnie = false, fetch = FetchType.EAGER) maska ​​prywatnej ProductSerialMask; @ Kolumna (unikatowa = true) @ManyToOne (opcjonalnie = false, pobranie = FetchType.EAGER) prywatna Grupa grupy; Mam dwa indeksy, ale gdy używasz w inny sposób, mam jeden indeks, że jest to połączenie dwóch kolumn? –

12

Oprócz odpowiedzi Boaz za ....

@UniqueConstraint pozwala nazwy ograniczenie, natomiast @Column(unique = true) generuje losową nazwę (np UK_3u5h7y36qqa13y3mauc5xxayq).

Czasami pomocne może być ustalenie, z którą tabelą wiąże się wiązanie. Np .:

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

Oprócz @ Boaz i odpowiedzi @ vegemite4me za ....

Poprzez wdrożenie ImplicitNamingStrategy można tworzyć reguły automatycznego nazywania ograniczeń. Uwaga dodać swoją strategię nazewnictwa do metadataBuilder podczas inicjalizacji Hibernate:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy()); 

Działa na @UniqueConstraint, ale nie dla @Column(unique = true), który zawsze generuje losową nazwę (np UK_3u5h7y36qqa13y3mauc5xxayq).

Istnieje raport o błędzie, aby rozwiązać ten problem, więc , jeśli możesz, zagłosuj tam, aby to zaimplementować. Tutaj: https://hibernate.atlassian.net/browse/HHH-11586

Dzięki.

Powiązane problemy