ทำความรู้จักกับ EntityManager

ใน JPA Spec มีรูปแบบ EntityManager หรือ Persistence Context ไว้หลายแบบประกอบด้วย

  • ชนิดของ Persistence Context
    • Extended
    • Transaction
  • การจัดการกับ EntityManager
    • Container Managed
    • Application Managed
  • ชนิด Transaction ของ EntityManager
    • RESOURCE_LOCAL
    • JTA

อ่าน spec ได้จาก JSR 220 Specification

จากองค์ประกอบด้านบนจะมีบางอย่างเท่านั้นที่ใช้ได้ใน Java EE และเช่นกันจะมีบางอย่างเท่านั้นที่ใช้ได้ใน Java SE โดยในบทความนี้ผมจะยกข้อแตกต่างของแต่ละแบบเปรียบเทียบกัน…

Extended vs Transaction Persistence Context Type
Persistence Context type เป็นหนึ่งฟีเจอร์ของ EntityManager โดยค่าดีฟอลต์แล้วจะเป็น Transactional ใช้สำหรับการแก้ไข หรือ flush managed bean (managed bean คือ bean ที่ยังอยู่ใน scope ของ transaction และ bean นั้นจะถูกบันทึกการเปลี่ยนแปลงจนกว่า transaction จะ commit และหลังจาก transaction commit แล้วเราจะเรียกสถานะของ bean นั้นว่า detatched ซึ่งการเปลี่ยนแปลงค่าของ bean จะไม่มีผลกับ Persistence Context อีก)

ส่วน Extended นั้นจะใช้ได้กับ Stateful EJB(SFSB = Stateful Session Bean) เท่านั้น เพราะ SFSB ต้องมี state ซึ่งหลังจากจบ method แล้วไม่ได้หมายความว่าต้องจบ Transaction ด้วย

แต่สำหรับ SLSF(Stateless Session Bean) นั้นต่างออกไปเมื่อเราจบ business method แล้ว transaction ควรสิ้นสุดลง เพราะเมื่อเราเรียก method นั้นใหม่เราต้องทำการใช้ EJB instance ตัวใหม่ ซึ่งทำให้ หนึ่ง Method จึงเท่ากับหนึ่ง Transaction ดังนั้น SLSB จึงใช้ได้เฉพาะ Transaction type เท่านั้น

ข้อมูลเพิ่มเติมของ Persistence Context type อ่านได้จาก JSR 220 ใน JSR-000220 Enterprise JavaBeans 3.0 Final Release (persistence) หัวข้อที่ 5.6.1 และ 5.6.2

Persistence Context Type เราสามารถเลือก type ได้ตอนที่ EntityManager ถูก inject เข้ามาโดยเราสามารถเขียนโค๊ด

@PersistenceContext(type=javax.persistence.PersistenceContextType.EXTENDED)
EntityManager em;

ซึ่ง default ถ้าเราไม่กำหนดจะมี type เป็น javax.persistence.PersistenceContextType.TRANSACTION

โดยการใช้งาน Persistence Context Type จะใช้งานได้เมื่อเป็น Container Managed EntityManager เท่านั้น ในกรณีของ Application managed EntityManager จะแตกต่างออกไป สามารถอ่านเพิ่มเติมได้จากหัวข้อ 5.7 ของ JSR-000220 Enterprise JavaBeans 3.0 Final Release (persistence)

Container Managed vs Application Managed
โดยปกติแล้วเรามักจะทำการ inject EntityManager โดยใช้ @PersistenceContext เช่น

@PersistenceContext
EntityManager em;

โดยการเขียนแบบข้างบนเป็นการบอกให้ Container Inject EntityManager มาให้เรา นั้นหมายความว่าการเรียกใช้งานแบบนี้เป็น Container Managed EntityManager 😛

แต่ในทางกลับกัน ถ้าเราสร้าง EntityManager ขึ้นมาเองจาก EntityManagerFactory

@PersistenceUnit
EntityManagerFactory emf;
...
emf.createEntityManager();
...

ซึ่งวิธีนี้เราจะได้ EntityManager จากการเรียกใช้ method createEntityManager() และวิธีการนี้เองเราเรียกมันว่า Application Managed EntityManager เมื่อเราสร้าง EntityManager ขึ้นมาเราต้องเป็นคนปิด EntityManager ด้วยโดยเราต้องเขียนคำสั่งการ Manage(สร้าง และ ปิด) มันไว้ใน Application ของเรานั้นเองครับ

Appliction Managed PersistenceContext นั้นจะมีขนิดของ PersistenceContext Type เป็น extended เพราะว่าเราสามารถควบคมการเปิด ปิดของ Persistence Context ได้ด้วยตัวเราเอง ดังนั้นมันจึงทำงานข้าม business method หลายๆอันได้

JTA vs RESOURCE_LOCAL



me on google plus+Jirawong Wongdokpuang