2013-03-12 43 views
48

Sự khác biệt giữa @UniqueConstraint@Column (unique = true)?@UniqueConstraint và @Column (unique = true) trong chú thích ngủ đông

Ví dụ:

@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; 
+2

Lưu ý: Với Hibernate 5.4, khi tôi thêm 'unique = true', chỉ mục không được thêm vào bởi chương trình tự động cập nhật. '@ UniqueConstraint' làm cho nó xuất hiện. Có thể là một lỗi. –

Trả lời

53

Như đã nói trước đây, @Column(unique = true) là một phím tắt để UniqueConstraint khi nó chỉ là một lĩnh vực duy nhất.

Từ ví dụ bạn đưa ra, có sự khác biệt rất lớn giữa cả hai.

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

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

Mã này ngụ ý rằng cả hai maskgroup phải là duy nhất, nhưng riêng rẽ. Điều đó có nghĩa là, ví dụ: nếu bạn có bản ghi có mặt nạ .id = 1 và cố gắng chèn một bản ghi khác với mask.id = 1, bạn sẽ gặp lỗi, vì cột đó phải có giá trị duy nhất . Cùng một cách cho nhóm.

Mặt khác,

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

ngụ ý rằng các giá trị của mặt nạ + nhóm kết hợp phải là duy nhất. Điều đó có nghĩa bạn có thể có, ví dụ, một kỷ lục với mask.id = 1group.id = 1, và nếu bạn cố gắng để chèn bản ghi khác với mask.id = 1group.id = 2, nó sẽ được chèn thành công, trong khi trong trường hợp đầu tiên nó sẽ không.

Nếu bạn muốn có cả mặt nạ và nhóm phải là duy nhất riêng biệt và đó ở cấp lớp, bạn phải viết mã như sau:

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

này có tác dụng tương tự như khối mã đầu tiên.

+0

Khi ràng buộc duy nhất được tạo ra tôi có thể tham chiếu ràng buộc theo tên trong Kho lưu trữ JPA của tôi để truy vấn về điều đó không? – jDub9

25

Từ các tài liệu Java EE:

public abstract boolean unique 

(Tùy chọn) Cho dù tài sản là một khóa duy nhất. Đây là lối tắt cho chú thích UniqueConstraint ở cấp bảng và hữu ích khi khóa duy nhất hạn chế chỉ là một trường duy nhất. Ràng buộc này áp dụng ngoài bất kỳ ràng buộc nào đòi hỏi phải có ánh xạ khóa chính và các ràng buộc được chỉ định ở cấp bảng.

Xem doc

+0

vì vậy khi tôi sử dụng mã này: @Column (unique = true) @ManyToOne (tùy chọn = false, fetch = FetchType.EAGER) riêngSản phẩmSerialMask mặt nạ; @Column (unique = true) @ManyToOne (tùy chọn = false, fetch = FetchType.EAGER) nhóm Nhóm riêng tư; Tôi có hai chỉ mục nhưng khi sử dụng cách khác tôi có một chỉ mục là kết hợp hai cột? –

12

Ngoài câu trả lời Boaz của ....

@UniqueConstraint cho phép bạn tên chế, trong khi @Column(unique = true) tạo ra một tên ngẫu nhiên (ví dụ UK_3u5h7y36qqa13y3mauc5xxayq).

Đôi khi có thể hữu ích khi biết ràng buộc của bảng là gì. Ví dụ .:

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

Ngoài câu trả lời @ vegemite4me của @ Boaz và ....

Bằng cách thực hiện ImplicitNamingStrategy bạn có thể tạo các quy tắc để tự động đặt tên cho các ràng buộc. Lưu ý bạn thêm chiến lược đặt tên của mình vào metadataBuilder trong quá trình khởi Hibernate của:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy()); 

Nó hoạt động cho @UniqueConstraint, nhưng không phải cho @Column(unique = true), mà luôn luôn tạo ra một tên ngẫu nhiên (ví dụ UK_3u5h7y36qqa13y3mauc5xxayq).

Có báo cáo lỗi để giải quyết vấn đề này, vì vậy, nếu có thể, vui lòng bỏ phiếu ở đó để thực hiện việc này. Đây: https://hibernate.atlassian.net/browse/HHH-11586

Cảm ơn.

Các vấn đề liên quan