อะไรคือค่าที่เป็นไปได้ของการกำหนดค่า hbm2ddl.auto Hibernate และพวกเขาทำอะไร


1085

ฉันต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับการอัปเดตการส่งออกและค่าที่สามารถมอบให้hibernate.hbm2ddl.auto
ฉันต้องรู้เมื่อต้องใช้การอัปเดตและเมื่อใด และทางเลือกคืออะไร?

นี่คือการเปลี่ยนแปลงที่อาจเกิดขึ้นบนฐานข้อมูล:

  • ตารางใหม่
  • คอลัมน์ใหม่ในตารางเก่า
  • ลบคอลัมน์แล้ว
  • เปลี่ยนชนิดข้อมูลของคอลัมน์แล้ว
  • ประเภทของคอลัมน์เปลี่ยนคุณลักษณะของมัน
  • ตารางลดลง
  • ค่าของคอลัมน์มีการเปลี่ยนแปลง

ในแต่ละกรณีทางออกที่ดีที่สุดคืออะไร

คำตอบ:


1083

จากเอกสารชุมชน :

hibernate.hbm2ddl.auto ตรวจสอบหรือเอ็กซ์พอร์ตสกีมา DDL ไปยังฐานข้อมูลโดยอัตโนมัติเมื่อสร้าง SessionFactory ด้วยการสร้างแบบหล่นลง schema ของฐานข้อมูลจะถูกปล่อยทิ้งเมื่อ SessionFactory ถูกปิดอย่างชัดเจน

เช่นตรวจสอบ | อัปเดต | สร้าง | สร้างวาง

ดังนั้นรายการของตัวเลือกที่เป็นไปได้คือ

  • ตรวจสอบ : ตรวจสอบความถูกต้องคีทำให้ไม่มีการเปลี่ยนแปลงไปยังฐานข้อมูล
  • update : อัปเดตสคีมา
  • สร้าง : สร้างสคีมาทำลายข้อมูลก่อนหน้า
  • create-drop : ดร็อปสกีมาเมื่อ SessionFactory ถูกปิดอย่างชัดเจนโดยทั่วไปเมื่อแอปพลิเคชันหยุดทำงาน
  • none : ไม่ทำอะไรกับ schema, ทำให้ไม่มีการเปลี่ยนแปลงฐานข้อมูล

ดูเหมือนว่าตัวเลือกเหล่านี้มีวัตถุประสงค์เพื่อเป็นเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์และไม่อำนวยความสะดวกให้กับฐานข้อมูลระดับการผลิตใด ๆ คุณอาจต้องการดูคำถามต่อไปนี้ ไฮเบอร์เนต: hbm2ddl.auto = อัพเดตในการผลิต?


14
เพียงแค่อ่านเอกสารจำศีล ... สำหรับค่าที่ถูกต้องมันบอกว่า: "เช่น" ... มีค่าที่ถูกต้องอื่น ๆ อีกหรือไม่?
Ta Sas

16
ฉันคิดว่ามันพูดว่า "เช่น" เพราะมันเป็นเพียงเอกสารชุมชนถ้าใครบางคนสนใจในค่าที่เป็นไปได้ทั้งหมดมันสามารถพบได้ใน javadoc ของ Hibernate (และใช่มีเพียงสี่ตัวเลือกเท่านั้นที่มีอยู่) docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/…
szegedi

4
validate พูดว่า validate schema มันหมายความว่าอะไรกันแน่?
Hussain Akhtar Wahid 'Ghouri'

6
นอกจากนี้คุณยังสามารถใช้ 'aardvark' หรือ 'pigeon' หรือคำอื่น ๆ หากคุณต้องการจำศีลที่จะทำอะไร ไม่ใช่ว่าฉันจะแนะนำอย่างนั้น!
Ward

2
เพิ่มเล็กน้อยในตัวเลือกการสร้าง หากใช้ตัวเลือกนี้จะไม่ลบทั้งสคีมาแทนจะปล่อยตารางที่มีการแมปพร้อมใช้งานในขณะที่เรียกใช้ตัวเลือกนี้ ตัวอย่างเช่นหากฐานข้อมูลที่มี Schema S มีตาราง A, B, C และรหัส Java มีการแมปสำหรับ A และ B เท่านั้นไฮเบอร์เนตจะไม่ลบตาราง C
Aditya

194

นอกจากนี้ยังมีค่าที่ไม่มีเอกสารเป็น "none" เพื่อปิดใช้งานทั้งหมด


7
สิ่งนี้มีประโยชน์มากเนื่องจากการตรวจสอบความถูกต้องของสคีมาของฮิเบอร์เนทล้มเหลวในบางครั้งสำหรับสคีมาที่ถูกต้องสมบูรณ์
Michael Piefel

ฉันเพิ่งจะขออะไรแบบนี้ ความตั้งใจของฉันคือการลดเวลาเริ่มต้น
digao_mb

46
'สตริงที่ว่างเปล่า' ดีกว่า 'ไม่มี' ในการใช้ 'none' คุณจะได้รับข้อความเตือน: org.hibernate.cfg.SettingsFactory - ค่าที่ไม่รู้จักสำหรับ "hibernate.hbm2ddl.auto": none
okwap

14
ฉันแก้ไขมันแล้ว เพิ่ม "none" เป็นค่าคงที่ที่ถูกต้องอย่างชัดเจน
Sanne

9
ฉันชอบ "hibernate.hbm2ddl.auto = potato" เหนือคนอื่น ๆstackoverflow.com/a/15810379/838444
Sneg

161

คุณสมบัติการกำหนดค่าที่เรียกว่า hibernate.hbm2ddl.auto

ในสภาพแวดล้อมการพัฒนาของเราเราตั้งค่าhibernate.hbm2ddl.auto=create-dropให้วางและสร้างฐานข้อมูลที่สะอาดทุกครั้งที่เราปรับใช้เพื่อให้ฐานข้อมูลของเราอยู่ในสถานะที่รู้จัก

ในทางทฤษฎีคุณสามารถตั้งค่าhibernate.hbm2ddl.auto=updateให้อัปเดตฐานข้อมูลของคุณด้วยการเปลี่ยนแปลงโมเดลของคุณ แต่ฉันจะไม่เชื่อมั่นในฐานข้อมูลการผลิต เอกสารเวอร์ชันก่อนหน้านี้กล่าวว่านี่เป็นการทดลองอย่างน้อยที่สุด ฉันไม่ทราบสถานะปัจจุบัน

ดังนั้นสำหรับฐานข้อมูลการผลิตของเราอย่าตั้งค่าhibernate.hbm2ddl.auto- ค่าเริ่มต้นคือไม่มีการเปลี่ยนแปลงฐานข้อมูล แต่เราสร้างสคริปต์การอัปเดต SQL DDL ด้วยตนเองที่ใช้การเปลี่ยนแปลงจากรุ่นหนึ่งเป็นรุ่นถัดไป


5
ที่จริงแล้วตามเอกสารประกอบ create-drop จะสร้างตารางฐานข้อมูลและวางตารางลงเมื่อโรงงานเซสชันปิดอย่างชัดเจน มันไม่ได้วางตารางเมื่อโรงงานเซสชั่นจะถูกสร้างขึ้น
Frans

4
ไม่ทั้ง create-drop และ create ปล่อยตารางเมื่อสร้าง sessionfactory จากนั้น create-drop จะลดลงเช่นกันเมื่อปิด sessionfactory ดูstackoverflow.com/a/6752698/1536382
Testo Testini

การสร้าง hibernate.hbm2ddl.auto = การสร้างแบบหล่นในการผลิตสามารถนำไปสู่การหมดเวลาเชื่อมต่อหลายครั้งในการผลิตได้หรือไม่
METTAIBI

51

ฉันจะใช้liquibaseเพื่ออัพเดทฐานข้อมูลของคุณ คุณลักษณะการอัพเดตสกีมาของไฮเบอร์เนตนั้นใช้ได้สำหรับนักพัฒนาเท่านั้นในขณะที่พวกเขากำลังพัฒนาคุณลักษณะใหม่ ในสถานการณ์การผลิตการอัพเกรด db จำเป็นต้องได้รับการจัดการอย่างระมัดระวังมากขึ้น


6
ดูstackoverflow.com/questions/221379/…สำหรับสาเหตุที่คุณไม่ควรใช้ hbm2ddl เพื่อการผลิต
Nathan Voxland

51

แม้ว่ามันจะเป็นการโพสต์ที่ค่อนข้างเก่า แต่เนื่องจากฉันได้ทำการค้นคว้าบางอย่างเกี่ยวกับหัวข้อจึงคิดว่าจะแบ่งปันมัน

hibernate.hbm2ddl.auto

ตามเอกสารมันสามารถมีค่าที่ใช้ได้สี่ค่า:

สร้าง | อัปเดต | ตรวจสอบ | สร้างวาง

ต่อไปนี้เป็นคำอธิบายของพฤติกรรมที่แสดงโดยค่าเหล่านี้:

  • สร้าง : - สร้างสคีมาข้อมูลที่มีอยู่ก่อนหน้า (ถ้ามี) ในสคีมานั้นหายไป
  • update: - อัปเดตสคีมาด้วยค่าที่กำหนด
  • ตรวจสอบ: - ตรวจสอบสคีมา มันทำให้ไม่มีการเปลี่ยนแปลงในฐานข้อมูล
  • create-drop: - สร้าง schema ด้วยการทำลายข้อมูลที่มีอยู่ก่อนหน้า (ถ้ามี) นอกจากนี้ยังปล่อยสคีมาฐานข้อมูลเมื่อ SessionFactory ถูกปิด

ต่อไปนี้เป็นจุดสำคัญที่น่าสังเกต:

  • ในกรณีที่มีการอัพเดทหากไม่มีสคีมาอยู่ในฐานข้อมูลสคีมาจะถูกสร้างขึ้น
  • ในกรณีที่ตรวจสอบความถูกต้องหากไม่มีสคีมาในฐานข้อมูลมันจะไม่ถูกสร้างขึ้น แต่จะทำให้เกิดข้อผิดพลาดแทน: -Table not found:<table name>
  • ในกรณีของการสร้างลดลงสคีมาจะไม่ลดลงเมื่อปิดเซสชั่น มันลดลงเฉพาะเมื่อปิด SessionFactory
  • ในกรณีที่ฉันให้ค่าใด ๆ กับคุณสมบัตินี้ (พูด abc แทนที่จะเป็นสี่ค่าที่กล่าวถึงข้างต้น) หรือเป็นค่าว่าง มันแสดงพฤติกรรมดังต่อไปนี้:

    หากคีไม่อยู่ในฐานข้อมูล: - มันจะสร้างสคีมา

    หากมีสคีมาในฐานข้อมูล: - อัปเดตสคีมา


เป็นจุดที่สำคัญอย่างยิ่งที่สคีมาจะถูกสร้างขึ้นหากไม่มีอยู่เมื่อใช้ "อัปเดต"
yuranos

create-drop นั้นขัดแย้งกันเมื่อเปรียบเทียบคำสั่ง "คำอธิบายพฤติกรรม" และ "จุดสำคัญ"
VNT

2
ความแตกต่างระหว่างการอัปเดตและว่างเปล่าคืออะไร
yashjain12yj

46

ก่อนอื่นค่าที่เป็นไปได้สำหรับhbm2ddlคุณสมบัติการกำหนดค่าคือค่าต่อไปนี้:

  • none- ไม่มีการดำเนินการ สคีมาจะไม่ถูกสร้างขึ้น
  • create-only - สคีมาฐานข้อมูลจะถูกสร้างขึ้น
  • drop - สกีมาฐานข้อมูลจะถูกดร็อปและสร้างหลังจากนั้น
  • create - สกีมาฐานข้อมูลจะถูกดร็อปและสร้างหลังจากนั้น
  • create-drop- สกีมาฐานข้อมูลจะถูกดร็อปและสร้างหลังจากนั้น เมื่อปิดตัวSessionFactoryสกีมาฐานข้อมูลจะถูกดร็อป
  • validate - สคีมาฐานข้อมูลจะถูกตรวจสอบความถูกต้องโดยใช้การจับคู่เอนทิตี
  • update - สคีมาฐานข้อมูลจะถูกอัพเดตโดยการเปรียบเทียบสคีมาฐานข้อมูลที่มีอยู่กับการแมปเอนทิตี

ฉันทุ่มเทโพสต์บล็อกสำหรับกลยุทธ์การสร้าง DDL ที่ใช้กันทั่วไปมากที่สุด:

  1. hibernate.hbm2ddl.auto="update"จะสะดวก แต่มีความยืดหยุ่นน้อยลงหากคุณวางแผนที่จะเพิ่มฟังก์ชั่นหรือรันสคริปต์ที่กำหนดเองบางส่วน
  2. วิธีการที่ยืดหยุ่นมากที่สุดคือการใช้เสียหาย

อย่างไรก็ตามแม้ว่าคุณจะใช้ Flyway คุณยังสามารถสร้างสคริปต์การย้ายข้อมูลเริ่มต้นได้โดยใช้ hbm2ddl ในบทความนี้คุณสามารถดูว่าคุณสามารถรวม JPA Entity Model เข้ากับ jOOQ Table Model ได้อย่างไร


27

hibernate.hbm2ddl.auto ตรวจสอบและส่งออก DDL ไปยังสคีมาโดยอัตโนมัติเมื่อสร้าง sessionFactory

โดยค่าเริ่มต้นจะไม่ทำการสร้างหรือดัดแปลงใด ๆ บนฐานข้อมูล หากผู้ใช้ตั้งค่าหนึ่งในค่าด้านล่างแสดงว่าสคีมาของ DDL เปลี่ยนแปลงโดยอัตโนมัติ

  • สร้าง - ทำการสร้างสคีมา

    <entry key="hibernate.hbm2ddl.auto" value="create">
  • update - อัปเดตสคีมาที่มีอยู่

    <entry key="hibernate.hbm2ddl.auto" value="update">
  • ตรวจสอบ - ตรวจสอบสคีมาที่มีอยู่

    <entry key="hibernate.hbm2ddl.auto" value="validate">
  • create-drop - สร้างและวางสคีมาโดยอัตโนมัติเมื่อเซสชันเริ่มต้นและสิ้นสุด

    <entry key="hibernate.hbm2ddl.auto" value="create-drop">

2
สิ่งที่เกี่ยวกับ <entry key = "hibernate.hbm2ddl.auto" value = "none">?
VNT

17

หากคุณไม่ต้องการใช้ Strings ในแอพของคุณและกำลังมองหาค่าคงที่ที่กำหนดไว้ล่วงหน้าให้ดูที่org.hibernate.cfg.AvailableSettingsคลาสที่รวมอยู่ใน Hibernate JAR ซึ่งคุณจะพบค่าคงที่สำหรับการตั้งค่าที่เป็นไปได้ทั้งหมด ในกรณีของคุณเช่น:

/**
 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
 */
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";

5
เหตุใดการอ้างอิงถึงไฟล์แหล่งยาว 700+ บรรทัดด้านบนตอบตรงด้วยเกือบ 500 vole ups?
Pavel Niedoba

... คำถามนั้นไม่สมเหตุสมผลเลย ทำไมมีอะไร ทำไมฉันถึงอยู่ที่นี่ด้วยล่ะ
specializt

8
  • validate: ตรวจสอบสคีมาไม่มีการเปลี่ยนแปลงเกิดขึ้นกับฐานข้อมูล
  • update: อัปเดตสคีมาด้วยแบบสอบถามแบบใช้งานปัจจุบัน
  • create: สร้างสคีมาใหม่ทุกครั้งและทำลายข้อมูลก่อนหน้า
  • create-drop: วางสคีมาเมื่อแอปพลิเคชันหยุดทำงานหรือ SessionFactory ถูกปิดอย่างชัดเจน

เอกสารอ้างอิง 'เป็นทางการ' คืออะไร? - แค่สงสัย ...
Dirk Schumacher

7

ฉันคิดว่าคุณควรจะมีสมาธิในการ

SchemaExport Class 

คลาสนี้ทำให้การกำหนดค่าของคุณเป็นแบบไดนามิกดังนั้นคุณจึงสามารถเลือกห้องสวีทที่คุณชอบที่สุด ...

ชำระเงิน[SchemaExport]


4

validate: มันตรวจสอบสคีและไม่เปลี่ยนแปลงไปยังฐานข้อมูล
สมมติว่าคุณได้เพิ่มคอลัมน์ใหม่ในไฟล์การจับคู่และดำเนินการแทรกมันจะโยนข้อยกเว้น "คอลัมน์ XYZ หายไป" เนื่องจากสคีมาที่มีอยู่นั้นแตกต่างจากวัตถุที่คุณจะแทรก หากคุณเปลี่ยนตารางโดยเพิ่มคอลัมน์ใหม่ด้วยตนเองจากนั้นดำเนินการแทรกดังนั้นมันจะแทรกคอลัมน์ทั้งหมดพร้อมกับคอลัมน์ใหม่ไปยังตาราง หมายความว่ามันไม่ได้ทำการเปลี่ยนแปลงใด ๆ / เปลี่ยนแปลง schema / ตารางที่มีอยู่

update: แก้ไขตารางที่มีอยู่ในฐานข้อมูลเมื่อคุณดำเนินการ คุณสามารถเพิ่มหรือลบคอลัมน์ได้ด้วยตัวเลือกของ hbm2ddl นี้ แต่ถ้าคุณกำลังจะเพิ่มคอลัมน์ใหม่ที่เป็น 'NOT NULL' มันจะไม่สนใจการเพิ่มคอลัมน์นั้นไปยังฐานข้อมูล เนื่องจากตารางจะต้องว่างถ้าคุณต้องการเพิ่มคอลัมน์ 'NOT NULL' ลงในตารางที่มีอยู่


3

ตั้งแต่ 5.0คุณสามารถค้นหาค่าเหล่านี้ในแบบเฉพาะEnum: org.hibernate.boot.SchemaAutoTooling(ปรับปรุงด้วยค่าNONEตั้งแต่ 5.2)

หรือดียิ่งขึ้นตั้งแต่ 5.1คุณสามารถใช้สิ่งที่รวมการกระทำ JPA 2 และ "มรดก" DDL ไฮเบอร์เนตorg.hibernate.tool.schema.Action Enum

แต่คุณยังไม่สามารถกำหนดค่าDataSourceด้วยวิธีนี้โดยทางโปรแกรม มันจะดีกว่าที่จะใช้สิ่งนี้ร่วมกับorg.hibernate.cfg.AvailableSettings#HBM2DDL_AUTOแต่โค้ดปัจจุบันคาดว่าจะมีStringค่า (ข้อความที่ตัดตอนมาจากSessionFactoryBuilderImpl):

this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );

…และenumคุณค่าภายในของทั้งคู่org.hibernate.boot.SchemaAutoToolingและorg.hibernate.tool.schema.Actionไม่เปิดเผยต่อสาธารณะ

ต่อไปนี้เป็นตัวอย่างการDataSourceตั้งค่าทางโปรแกรม(ใช้ในแอพพลิเคชั่น Spring Boot ของฉัน) ซึ่งใช้ gambit ขอบคุณ.name().toLowerCase()แต่ใช้งานได้กับค่าที่ไม่มีเส้นประเท่านั้น (ไม่ใช่create-dropตัวอย่าง):

@Bean(name = ENTITY_MANAGER_NAME)
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier(DATA_SOURCE_NAME) DataSource internalDataSource) {

    Map<String, Object> properties = new HashMap<>();
    properties.put(AvailableSettings.HBM2DDL_AUTO, SchemaAutoTooling.CREATE.name().toLowerCase());
    properties.put(AvailableSettings.DIALECT, H2Dialect.class.getName());

    return builder
            .dataSource(internalDataSource)
            .packages(JpaModelsScanEntry.class, Jsr310JpaConverters.class)
            .persistenceUnit(PERSISTENCE_UNIT_NAME)
            .properties(properties)
            .build();
}

0

ผู้ที่ค้นหาค่าเริ่มต้น ...

มันถูกเขียนในซอร์สโค้ดที่เวอร์ชั่น 2.0.5 ของ spring-boot และ 1.1.0 ที่ JpaProperties:

    /**
     * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
     * property. Defaults to "create-drop" when using an embedded database and no
     * schema manager was detected. Otherwise, defaults to "none".
     */
    private String ddlAuto;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.