ความแตกต่างระหว่าง persist () และ merge () ใน JPA และ Hibernate คืออะไร?


119

ความแตกต่างระหว่าง persist () และ merge () ใน Hibernate คืออะไร?

persist() สามารถสร้างแบบสอบถาม UPDATE & INSERT เช่น:

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

ในกรณีนี้จะมีการสร้างแบบสอบถามดังนี้:

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

ดังนั้นpersist()วิธีการสามารถสร้างส่วนแทรกและการอัปเดต

ขณะนี้มีmerge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

นี่คือสิ่งที่ฉันเห็นในฐานข้อมูล:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

ตอนนี้อัปเดตบันทึกโดยใช้ไฟล์ merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

นี่คือสิ่งที่ฉันเห็นในฐานข้อมูล:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley

7
javadoc มีความชัดเจนมากเกี่ยวกับสิ่งที่พวกเขาทำและความแตกต่างคืออะไร คุณอ่านและเข้าใจมันหรือยัง?
skaffman


คำตอบ:


144

ข้อกำหนดของ JPAมีคำอธิบายที่แม่นยำมากเกี่ยวกับความหมายของการดำเนินการเหล่านี้ดีกว่าใน javadoc:

ความหมายของการ ดำเนินการคงอยู่ที่ใช้กับเอนทิตี X มีดังต่อไปนี้:

  • ถ้า X เป็นเอนทิตีใหม่จะมีการจัดการ เอนทิตี X จะถูกป้อนลงในฐานข้อมูลในเวลาหรือก่อนการทำธุรกรรมหรือเป็นผลมาจากการดำเนินการล้าง

  • ถ้า X เป็นเอนทิตีที่มีการจัดการที่มีอยู่ก่อนหน้านี้จะถูกละเว้นโดยการดำเนินการที่มีอยู่ อย่างไรก็ตามการดำเนินการยังคงอยู่ในระดับล่างไปยังหน่วยงานอ้างอิงโดย X ถ้าความสัมพันธ์จาก X ไปยังหน่วยงานอื่น ๆ เหล่านี้จะมีคำอธิบายประกอบกับ cascade=PERSISTหรือcascade=ALL ค่าองค์ประกอบคำอธิบายประกอบหรือระบุไว้กับเทียบเท่าองค์ประกอบบ่ง XML

  • ถ้า X เป็นเอนทิตีที่ถูกลบออกจะถูกจัดการ

  • หาก X เป็นวัตถุแยกชิ้นส่วน EntityExistsExceptionอาจถูกโยนทิ้งเมื่อมีการเรียกใช้การดำเนินการที่ยังคงมีอยู่หรือสิ่งEntityExistsExceptionอื่นPersistenceExceptionอาจถูกโยนทิ้งในเวลาล้างหรือคอมมิต

  • สำหรับเอนทิตี Y ทั้งหมดที่อ้างถึงโดยความสัมพันธ์จาก X ถ้าความสัมพันธ์กับ Y ถูกใส่คำอธิบายประกอบด้วยค่าองค์ประกอบแบบเรียงซ้อน cascade=PERSISTหรือcascade=ALLการดำเนินการคงอยู่จะถูกนำไปใช้กับ Y


ความหมายของการดำเนินการผสานที่ใช้กับเอนทิตี X มีดังนี้:

  • ถ้า X เป็นเอนทิตีแยกสถานะของ X จะถูกคัดลอกไปยังอินสแตนซ์เอนทิตีที่มีการจัดการที่มีอยู่แล้ว X 'ของข้อมูลประจำตัวเดียวกันหรือสร้างสำเนา X' ของ X ที่มีการจัดการใหม่

  • ถ้า X เป็นอินสแตนซ์เอนทิตีใหม่อินสแตนซ์เอนทิตีที่มีการจัดการใหม่ X 'จะถูกสร้างขึ้นและสถานะของ X จะถูกคัดลอกไปยังอินสแตนซ์เอนทิตีที่มีการจัดการใหม่ X'

  • ถ้า X เป็นอินสแตนซ์เอนทิตีที่ถูกลบออก IllegalArgumentExceptionการดำเนินการผสานจะถูกโยนทิ้ง (มิฉะนั้นการคอมมิตธุรกรรมจะล้มเหลว)

  • ถ้า X เป็นเอนทิตีที่มีการจัดการจะถูกละเว้นโดยการดำเนินการผสานอย่างไรก็ตามการดำเนินการผสานจะเรียงซ้อนกับเอนทิตีที่อ้างอิงโดยความสัมพันธ์จาก X หากความสัมพันธ์เหล่านี้ได้รับการใส่คำอธิบายประกอบด้วยค่าองค์ประกอบแบบเรียงซ้อนcascade=MERGEหรือ cascade=ALLคำอธิบายประกอบ

  • สำหรับเอนทิตี Y ทั้งหมดที่อ้างอิงโดยความสัมพันธ์จาก X ที่มีค่าองค์ประกอบแบบเรียงซ้อนcascade=MERGEหรือcascade=ALLY จะถูกรวมแบบวนซ้ำเป็น Y ' สำหรับ Y ทั้งหมดที่อ้างถึงโดย X X 'จะถูกตั้งค่าให้อ้างอิง Y' (โปรดทราบว่าถ้า X ได้รับการจัดการแล้ว X จะเป็นวัตถุเดียวกันกับ X ')

  • ถ้า X เป็นเอนทิตีที่รวมเข้ากับ X 'โดยมีการอ้างอิงถึงเอนทิตี Y อื่นโดยที่cascade=MERGEหรือcascade=ALLไม่ได้ระบุไว้การนำทางของการเชื่อมโยงเดียวกันจาก X จะให้การอ้างอิงไปยังอ็อบเจ็กต์ที่มีการจัดการ Y' ที่มีเอกลักษณ์ถาวรเดียวกันกับ Y


ขอบคุณสำหรับข้อมูล. ฉันเห็นความหมายของคำจำกัดความทั้งสอง แต่คำถามเกี่ยวกับความแตกต่างระหว่างพวกเขา บางทีอาจนำเสนอรายการของสถานะและ 2 ส่วนย่อยสำหรับพฤติกรรมที่แตกต่างกันของpersistvs merge?
AlikElzin-kilaka

25

นี้มาจากJPA. ด้วยวิธีง่ายๆ:

  • persist(entity) ควรใช้กับเอนทิตีใหม่ทั้งหมดเพื่อเพิ่มลงใน DB (หากเอนทิตีมีอยู่แล้วใน DB จะมี EntityExistsException throw)

  • merge(entity) ควรใช้เพื่อทำให้เอนทิตีกลับสู่บริบทการคงอยู่หากเอนทิตีถูกแยกออกและมีการเปลี่ยนแปลง


คุณช่วยเพิ่มแหล่งที่มาในคำอธิบายของคุณได้ไหม ขอบคุณ
AlikElzin-kilaka

@ AlikElzin-kilaka คำอธิบายดังกล่าวเท่าที่ฉันจำได้ฉันพบในหนังสือ "Beginning Java EE 7"
Krystian

12

ควรเรียกใช้คงอยู่ในเอนทิตีใหม่เท่านั้นในขณะที่การผสานมีจุดมุ่งหมายเพื่อแนบเอนทิตีแยกใหม่

หากคุณกำลังใช้ตัวสร้างที่ได้รับมอบหมายการใช้ merge แทนการคงอยู่อาจทำให้เกิดคำสั่ง SQL ซ้ำซ้อนดังนั้นจึงส่งผลต่อประสิทธิภาพ

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


1

ความแตกต่างที่สำคัญที่สุดคือ:

  • ในกรณีของpersistวิธีการหากเอนทิตีที่จะจัดการในบริบทการคงอยู่มีอยู่แล้วในบริบทการคงอยู่รายการใหม่จะถูกละเว้น (ไม่มีอะไรเกิดขึ้น)

  • แต่ในกรณีของmergeวิธีการเอนทิตีที่ได้รับการจัดการแล้วในบริบทการคงอยู่จะถูกแทนที่ด้วยเอนทิตีใหม่ (อัปเดต) และสำเนาของเอนทิตีที่อัปเดตนี้จะส่งคืนกลับ (จากนี้ไปควรทำการเปลี่ยนแปลงใด ๆ กับเอนทิตีที่ส่งคืนนี้หากคุณต้องการสะท้อนการเปลี่ยนแปลงของคุณในบริบทการคงอยู่)

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