@UniqueConstraint และ @Column (unique = true) ในคำอธิบายประกอบแบบจำศีล


105

ความแตกต่างระหว่างคืออะไร@UniqueConstraintและ@column (ที่ไม่ซ้ำกัน = 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;

2
หมายเหตุ: ด้วย Hibernate 5.4 เมื่อฉันเพิ่มunique=trueดัชนีจะไม่ถูกเพิ่มโดยตัวอัปเดตอัตโนมัติของแบบแผน @UniqueConstraintทำให้มันปรากฏขึ้น อาจเป็นข้อบกพร่อง
Ondra Žižka

คำตอบ:


148

ดังที่กล่าวไว้ก่อนหน้า@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.id = 1และgroup.id = 1และถ้าคุณพยายามแทรกระเบียนอื่นด้วยmask.id = 1และgroup.id = 2ก็จะถูกแทรก สำเร็จในขณะที่ในกรณีแรกจะทำไม่ได้

หากคุณต้องการให้ทั้งหน้ากากและกลุ่มไม่ซ้ำกันและในระดับชั้นเรียนคุณจะต้องเขียนรหัสดังนี้:

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

สิ่งนี้มีผลเช่นเดียวกับบล็อกรหัสแรก


เมื่อสร้างข้อ จำกัด เฉพาะแล้วฉันสามารถอ้างอิงข้อ จำกัด ตามชื่อในพื้นที่เก็บข้อมูล JPA ของฉันเพื่อสอบถามสิ่งนั้นได้หรือไม่
jDub9

@ jDub9 คุณไม่สามารถค้นหาดัชนี คุณสามารถสืบค้นมาสก์และคอลัมน์กลุ่มได้ในแบบสอบถามเดียวและจะใช้ดัชนีนั้นเพื่อการประมวลผลที่เร็วขึ้น (หากคุณโชคดี) แต่คุณไม่สามารถสืบค้นดัชนีได้
Dalibor Filus

ระวังว่า columnNames นั้นต้องเป็นชื่อจริงในฐานข้อมูล ควรเป็นmask_idและgroup_idหากคุณใช้กลยุทธ์การตั้งชื่อเริ่มต้น
หลอดทดลอง

27

จากเอกสาร Java EE:

public abstract boolean unique

(ไม่บังคับ) คุณสมบัตินั้นเป็นคีย์เฉพาะหรือไม่ นี่เป็นทางลัดสำหรับคำอธิบายประกอบ UniqueConstraint ที่ระดับตารางและมีประโยชน์เมื่อข้อ จำกัด ของคีย์เฉพาะเป็นเพียงฟิลด์เดียว ข้อ จำกัด นี้ใช้นอกเหนือจากข้อ จำกัด ใด ๆ ที่เกิดจากการแมปคีย์หลักและข้อ จำกัด ที่ระบุในระดับตาราง

ดูเอกสาร


ดังนั้นเมื่อฉันใช้รหัสนี้: @Column (unique = true) @ManyToOne (optional = false, fetch = FetchType.EAGER) มาสก์ ProductSerialMask ส่วนตัว @Column (unique = true) @ManyToOne (optional = false, fetch = FetchType.EAGER) กลุ่มกลุ่มส่วนตัว ฉันมีดัชนีสองตัว แต่เมื่อใช้วิธีอื่นฉันมีดัชนีเดียวที่รวมเป็นสองคอลัมน์?
navid_gh

22

นอกจากคำตอบของโบอาส ....

@UniqueConstraintให้คุณตั้งชื่อข้อ จำกัดในขณะที่@Column(unique = true)สร้างชื่อแบบสุ่ม (เช่นUK_3u5h7y36qqa13y3mauc5xxayq)

บางครั้งอาจเป็นประโยชน์หากทราบว่าข้อ จำกัด เกี่ยวข้องกับตารางใด เช่น:

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

5

นอกจากคำตอบของ @ Boaz และ @ vegemite4me แล้ว ....

โดยการดำเนินการImplicitNamingStrategyที่คุณอาจสร้างกฎสำหรับการตั้งชื่อ จำกัด โดยอัตโนมัติ โปรดทราบว่าคุณเพิ่มกลยุทธ์การตั้งชื่อของคุณในmetadataBuilderระหว่างการเริ่มต้นของ Hibernate:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

ใช้งาน@UniqueConstraintได้ แต่ไม่ใช่สำหรับ@Column(unique = true)ซึ่งจะสร้างชื่อแบบสุ่มเสมอ (เช่น UK_3u5h7y36qqa13y3mauc5xxayq)

มีรายงานข้อบกพร่องเพื่อแก้ไขปัญหานี้ดังนั้นหากทำได้โปรดลงคะแนนที่นั่นเพื่อดำเนินการนี้ ที่นี่: https://hibernate.atlassian.net/browse/HHH-11586

ขอบคุณ.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.