ความสับสน: @NotNull เทียบกับ @ คอลัมน์ (nullable = false) ด้วย JPA และไฮเบอร์เนต


242
  1. เมื่อพวกเขาปรากฏบนสนาม / ทะเยอทะยานของความ@Entityแตกต่างระหว่างพวกเขาคืออะไร? (ฉันยืนยันเอนทิตีผ่านไฮเบอร์เนต )

  2. กรอบและ / หรือข้อกำหนดใดที่แต่ละข้อเป็นของ

  3. @NotNulljavax.validation.constraintsตั้งอยู่ภายใน ในjavax.validation.constraints.NotNulljavadoc มันบอกว่า

    องค์ประกอบที่ใส่หมายเหตุประกอบจะต้องไม่เป็นโมฆะ

    แต่มันไม่ได้พูดถึงการเป็นตัวแทนขององค์ประกอบในฐานข้อมูลดังนั้นทำไมฉันจะเพิ่มข้อ จำกัดnullable=falseในคอลัมน์?

คำตอบ:


328

@NotNullคือบันทึกย่อการตรวจสอบความถูกต้อง JSR 303 Bean มันไม่มีส่วนเกี่ยวข้องกับข้อ จำกัด ของฐานข้อมูลเอง เนื่องจาก Hibernate เป็นการนำการอ้างอิงของ JSR 303 มาใช้อย่างชาญฉลาดจึงรับข้อ จำกัด เหล่านี้และแปลเป็นข้อ จำกัด ฐานข้อมูลให้คุณดังนั้นคุณจะได้รับสองสิ่งในราคาเดียว @Column(nullable = false)เป็นวิธี JPA ในการประกาศคอลัมน์ที่ไม่เป็นโมฆะ นั่นคืออดีตมีไว้สำหรับการตรวจสอบและหลังสำหรับการระบุรายละเอียดคีมาฐานข้อมูล คุณเพิ่งได้รับความช่วยเหลือพิเศษ (และยินดีต้อนรับ!) จากไฮเบอร์เนตในหมายเหตุประกอบการตรวจสอบ


2
ขอบคุณ! ดังนั้นถ้าฉันไม่ต้องการให้ JPA คงอยู่กับการดำเนินการไฮเบอร์เนต (เช่นเปลี่ยนเป็น EJB3) ฉันต้องใช้คำอธิบายประกอบทั้งสอง (เพื่อป้องกันการเป็นโมฆะทั้งในฟิลด์และคอลัมน์)
rapt

3
ฉันไม่รู้ ไม่มีข้อกำหนดที่ระบุว่าผู้ให้บริการ JPA ต้องรู้จักบันทึกย่อ JSR 303 แต่นั่นไม่ได้หมายความว่าผู้ให้บริการรายอื่นจะไม่ทำ ฉันไม่สามารถพูดได้ว่ามีหรือไม่มี
Ryan Stewart

7
ผู้ให้บริการ JPA ไม่จำเป็นต้องจัดเตรียมการปรับใช้ JSR303 แต่เป็นไปตามข้อกำหนดที่กำหนดเพื่อให้ความสามารถในการรวมเข้ากับการใช้งาน JSR303 ของบุคคลที่สาม ดังนั้นในขณะที่ Hibernate ให้บริการ JSR303 ด้วยเหตุผลใดก็ตามที่คุณตัดสินใจว่าจะไม่ใช้พวกเขาและไปกับคนอื่นหรือใช้การดำเนินการ JPA เช่น openJPA และใช้คนอื่นเพื่อให้ JSR303 นอกจากนี้การใช้งาน JPA ของ Hibernate ยังเป็น EJB3 ด้วย 'หากฉันต้องการให้ JPA คงอยู่ไม่ติดกับการใช้งานไฮเบอร์เนต (เช่นเปลี่ยนเป็น EJB3)' JPA เป็นส่วนหนึ่งของข้อกำหนด EJB3
Shahzeb

5
@Shahzeb: คำถามไม่ได้เกี่ยวกับผู้ที่สนับสนุน / ให้ตรวจสอบ JSR 303 มันเกี่ยวกับการที่ออม (s) รู้จัก JSR 303 คำอธิบายประกอบเช่น@NotNull, @Size, @Min, @Maxฯลฯ และแปลที่เป็นข้อ จำกัด ของฐานข้อมูล
Ryan Stewart

1
ใช่ แต่ความคิดเห็นของฉันใช้ได้ในบริบทของสิ่งที่ OP ถามในความคิดเห็นที่ตามมาซึ่งคุณไม่ทราบ
Shahzeb

18

ผู้ให้บริการ JPA รุ่นไฮเบอร์เนตล่าสุดใช้ข้อ จำกัด การตรวจสอบ bean (JSR 303) เช่นเดียว@NotNullกับ DDL โดยค่าเริ่มต้น (ขอบคุณhibernate.validator.apply_to_ddl propertyค่าเริ่มต้นtrue) แต่ไม่รับประกันว่าผู้ให้บริการ JPA รายอื่นจะทำหรือแม้กระทั่งมีความสามารถในการทำเช่นนั้น

คุณควรใช้คำอธิบายประกอบการตรวจสอบความถูกต้องของถั่ว@NotNullเพื่อให้แน่ใจว่าคุณสมบัติของถั่วถูกตั้งค่าเป็นค่าที่ไม่มีค่าว่างเมื่อตรวจสอบความถูกต้องของ Java beans ใน JVM (สิ่งนี้ไม่เกี่ยวข้องกับข้อ จำกัด ของฐานข้อมูล แต่ในสถานการณ์ส่วนใหญ่

คุณควรใช้คำอธิบายประกอบ JPA เพิ่มเติม@Column(nullable = false)เพื่อให้คำแนะนำกับผู้ให้บริการ jpa เพื่อสร้าง DDL ที่เหมาะสมสำหรับการสร้างคอลัมน์ตารางที่มีข้อ จำกัด ฐานข้อมูลที่คุณต้องการ หากคุณสามารถหรือต้องการพึ่งพาผู้ให้บริการ JPA เช่น Hibernate ซึ่งใช้ข้อ จำกัด การตรวจสอบความถูกต้องของถั่วกับ DDL ตามค่าเริ่มต้นคุณสามารถละเว้นได้


10

น่าสนใจที่จะทราบแหล่งที่มาทั้งหมดเน้นว่า @Column (nullable = false) จะใช้สำหรับการสร้าง DDL เท่านั้น

อย่างไรก็ตามแม้ว่าจะไม่มีการเพิ่มความคิดเห็น @NotNull และตัวเลือก hibernate.check_nullability ถูกตั้งค่าเป็นจริง Hibernate จะทำการตรวจสอบความถูกต้องของเอนทิตีที่จะคงอยู่

มันจะโยน PropertyValueException โดยบอกว่า "คุณสมบัติที่ไม่เป็นโมฆะอ้างอิงถึงค่า Null หรือค่าชั่วคราว" หากแอตทริบิวต์ nullable = false ไม่มีค่าแม้ว่าข้อ จำกัด ดังกล่าวจะไม่ถูกนำมาใช้ในชั้นฐานข้อมูล

ข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือก hibernate.check_nullability สามารถใช้ได้ที่นี่: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping


7

@ColumnคำอธิบายประกอบJPA

nullableแอตทริบิวต์ของ@Columnคำอธิบายประกอบมีจุดประสงค์สอง

  • มันถูกใช้โดยเครื่องมือสร้างสคีมา
  • มันถูกใช้โดยไฮเบอร์เนตในระหว่างการล้างเนื้อหาการคงอยู่

เครื่องมือสร้าง Schema

เครื่องมือสร้าง schema HBM2DDL จะแปล@Column(nullable = false)แอตทริบิวต์เอนทิตีเป็นNOT NULLข้อ จำกัด สำหรับคอลัมน์ตารางที่เกี่ยวข้องเมื่อสร้างCREATE TABLEคำสั่ง

ดังที่ฉันได้อธิบายไว้ในคู่มือผู้ใช้ไฮเบอร์เนตจะดีกว่าถ้าใช้เครื่องมือเช่นFlywayแทนที่จะใช้กลไก HBM2DDL เพื่อสร้างสกีมาฐานข้อมูล

การคงอยู่ของบริบท

เมื่อล้างบริบทการคงอยู่ Hibernate ORM ยังใช้@Column(nullable = false)แอตทริบิวต์เอนทิตี:

new Nullability( session ).checkNullability( values, persister, true );

หากการตรวจสอบล้มเหลว Hibernate จะส่งข้อความ a PropertyValueExceptionและป้องกันคำสั่ง INSERT หรือ UPDATE ที่จะต้องถูกดำเนินการ:

if ( !nullability[i] && value == null ) {
    //check basic level one nullablilty
    throw new PropertyValueException(
            "not-null property references a null or transient value",
            persister.getEntityName(),
            persister.getPropertyNames()[i]
        );    
}

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการทำงานของกลไกการล้าง Hibernate ตรวจสอบบทความนี้

@NotNullบันทึกย่อการตรวจสอบความถูกต้องของ Bean

@NotNullคำอธิบายประกอบจะถูกกำหนดโดย Bean และตรวจสอบเช่นเดียวกับ Hibernate ออมเป็นการนำ JPA นิยมมากที่สุดที่นิยมมากที่สุดการดำเนินการตรวจสอบ Bean เป็นHibernate ตรวจสอบกรอบ

เมื่อใช้ตัวConstraintViolationตรวจสอบความถูกต้องของHibernate พร้อมกับ Hibernate ORM ตัวตรวจสอบความถูกต้องของHibernate จะส่งสัญญาณเมื่อตรวจสอบความถูกต้องของเอนทิตี


เหตุใดคุณระบุว่าเส้นทางบินดีกว่าการสร้างสคีมา
Andronicus

1
นั่นเป็นการสังเกตที่ดี ฉันอัพเดตคำตอบด้วยลิงค์อ้างอิง
Vlad Mihalcea

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