Entity Lifecycle in JPA | چرخه حیات موجودیت در JPA
📖توضیحات درس
📄جزوه
مفاهیم کلیدی
- Entity Lifecycle
چرخه حیات یک Entity در JPA مجموعهای از وضعیتهایی است که یک شیء Entity در طول عمر خود طی میکند. این وضعیتها مشخص میکنند که آیا Entity توسط Persistence Context مدیریت میشود یا خیر. وضعیتهای اصلی شامل Transient، Managed، Detached و Removed هستند.
- Persistence Context
یک لایه میانی بین کد برنامه و دیتابیس است که مسئول مدیریت Entityها میباشد. این بخش تمام Entityهای لود شده را نگه میدارد، تغییرات آنها را دنبال میکند و در زمان مناسب آن تغییرات را با دیتابیس همگامسازی میکند.
در JPA این مفهوم توسط EntityManager پیادهسازی میشود.
- EntityManager
کلاس اصلی در JPA برای مدیریت Entityها است. این کلاس مسئول عملیاتهایی مانند persist، find، merge و remove بوده و در واقع مدیریت Persistence Context را برعهده دارد.
- Unit of Work
الگویی که در آن مجموعهای از عملیات دیتابیسی در قالب یک تراکنش انجام میشوند. Persistence Context در طول این تراکنش تغییرات روی Entityها را جمعآوری کرده و در پایان تراکنش آنها را به دیتابیس اعمال میکند.
- Managed Entity
Entityای که توسط EntityManager مدیریت میشود. هر تغییری که روی این Entity انجام شود، به صورت خودکار توسط JPA شناسایی شده و هنگام flush یا commit در دیتابیس اعمال میشود.
مثال:
EntityManager em = entityManagerFactory.createEntityManager();
List<Player> players = em.createQuery("from Player", Player.class)
.getResultList();
Player player = players.get(0);
player.setName("New Name");
در این مثال، بدون فراخوانی هیچ متدی برای update، تغییر نام به صورت خودکار در زمان commit در دیتابیس ذخیره میشود.
- Dirty Checking
مکانیزمی در JPA که تغییرات روی Managed Entityها را تشخیص میدهد. در پایان تراکنش، اگر Entity تغییر کرده باشد، JPA به صورت خودکار UPDATE مناسب را اجرا میکند.
- Detached Entity
Entityای که قبلاً Managed بوده اما دیگر توسط Persistence Context مدیریت نمیشود. این حالت معمولاً زمانی رخ میدهد که:
EntityManagerبسته شودentityManager.clear()اجرا شودentityManager.detach(entity)فراخوانی شود
تغییرات روی Detached Entity در دیتابیس ذخیره نمیشوند مگر اینکه دوباره به Persistence Context متصل شود.
- Reattach Entity
برای اتصال دوباره یک Detached Entity به Persistence Context از متد merge() استفاده میشود.
Player player = entityManager.merge(detachedPlayer);
بعد از این عملیات، Entity دوباره Managed میشود.
- Transient Entity
Entityای که تازه با new ساخته شده و هنوز در دیتابیس ذخیره نشده و توسط Persistence Context هم مدیریت نمیشود.
مثال:
Player player = new Player();
player.setName("Neymar");
برای تبدیل آن به Managed Entity از متد persist() استفاده میشود.
entityManager.persist(player);
- Removed Entity
Entityای که برای حذف از دیتابیس علامتگذاری شده است. این وضعیت زمانی ایجاد میشود که متد remove() فراخوانی شود.
entityManager.remove(player);
حذف واقعی در زمان flush یا commit انجام میشود.
موارد مصاحبه ای
- What is Persistence Context in JPA?
یک فضای مدیریتی است که EntityManager در آن Entityها را نگه میدارد، تغییرات آنها را track میکند و در پایان تراکنش آنها را با دیتابیس sync میکند.
- What are the main states of an Entity in JPA?
چهار وضعیت اصلی وجود دارد:
Transient، Managed، Detached و Removed.
- What is Dirty Checking?
مکانیزمی در JPA که تغییرات روی Managed Entityها را به صورت خودکار تشخیص داده و هنگام commit کوئری UPDATE مناسب را اجرا میکند.
- What is the difference between persist() and merge()?
persist() برای تبدیل یک Transient Entity به Managed استفاده میشود.
merge() برای اتصال دوباره یک Detached Entity به Persistence Context استفاده میشود.
- Why are changes automatically saved in Managed Entities?
چون Persistence Context تمام Managed Entityها را track میکند و در زمان flush تغییرات آنها را به دیتابیس اعمال میکند.
- What happens if you modify a Detached Entity?
تغییرات در دیتابیس ذخیره نمیشوند مگر اینکه Entity دوباره با merge() به Persistence Context متصل شود.
- When does SQL actually execute in JPA?
معمولاً در زمان flush یا transaction commit دستورات SQL مانند INSERT, UPDATE, DELETE اجرا میشوند.
سناریو کاربردی
فرض کنید یک Entity به نام Player در دیتابیس داریم.
مرحله اول: دریافت Entity از دیتابیس
Player player = entityManager.find(Player.class, 1L);
در این مرحله Entity در حالت Managed قرار دارد.
مرحله دوم: تغییر مقدار فیلد
player.setName("Gianluigi Buffon");
هیچ متد update فراخوانی نمیشود.
مرحله سوم: commit تراکنش
transaction.commit();
JPA از طریق Dirty Checking متوجه تغییر شده و دستور SQL زیر را اجرا میکند:
UPDATE player SET name = 'Gianluigi Buffon' WHERE id = 1
نکته مهم این است که برنامهنویس مستقیماً هیچ دستور update ننوشته است.
بیشتر بدانید
- Flush Mechanism
متد flush() باعث میشود تمام تغییرات موجود در Persistence Context فوراً به دیتابیس ارسال شوند، بدون اینکه تراکنش commit شود.
entityManager.flush();
- Detach Entity
برای خارج کردن یک Entity از Persistence Context میتوان از:
entityManager.detach(entity);
یا
entityManager.clear();
استفاده کرد.
- Common Web Application Pattern
در بسیاری از اپلیکیشنهای وب، دادههای فرم به یک Entity تبدیل میشوند و سپس با merge() به Persistence Context متصل میشوند.
- Danger When Updating Detached Entities
اگر یک Detached Entity فقط بخشی از فیلدها را داشته باشد و با merge() ذخیره شود، ممکن است فیلدهای دیگر به صورت null در دیتابیس ذخیره شوند. بنابراین باید هنگام update کامل بودن دادهها بررسی شود.
- Automatic SQL Generation
یکی از مزایای JPA این است که توسعهدهنده بیشتر با Entityها کار میکند و JPA به صورت خودکار SQL مناسب (INSERT, UPDATE, DELETE) را تولید میکند.
