Методите persist() и merge() са част от интерфейса EntityManager и се използват за управление на Entity обекти и тяхното състояние спрямо persistence context (контекста на устойчивост). Важно е да разбираме какво правят и кога се използват.
✅ persist(entity)
Цел: Запазва нов обект (състояние NEW) в базата данни.
Поведение:
| Състояние на entity | Резултат при persist() |
|---|---|
NEW |
→ става MANAGED, ще бъде вкаран в БД |
MANAGED |
→ игнорира се |
REMOVED |
→ става MANAGED отново |
DETACHED |
→ Грешка (IllegalArgumentException) |
Ако използваш CascadeType.PERSIST, свързани обекти също ще бъдат persist-нати.
Пример:
Student s = new Student();
s.setName("Ivan");
em.persist(s); // s е нов, ще бъде добавен в базата
✅ merge(entity)
Цел: Актуализира или създава копие на даден обект, който може да е DETACHED.
Поведение:
| Състояние на entity | Резултат при merge() |
|---|---|
NEW |
→ създава нов MANAGED обект |
DETACHED |
→ копира стойностите в нов MANAGED |
MANAGED |
→ игнорира се |
REMOVED |
→ Грешка (IllegalArgumentException) |
Връща ново MANAGED копие на обекта. Оригиналният DETACHED обект не се управлява от EntityManager.
Пример:
Student detachedStudent = new Student();
detachedStudent.setId(5L);
detachedStudent.setName("Petar");
Student managedStudent = em.merge(detachedStudent); // получаваш ново управлявано копие
Кога да използваш кое?
| Цел | Използвай persist() |
Използвай merge() |
|---|---|---|
| Добавяне на нов запис | ✅ Да | ❌ Не е оптимално |
| Обновяване на запис след сериализация или от DTO | ❌ Не | ✅ Да |
Работиш с DETACHED обекти |
❌ Грешка | ✅ Подходящо |
| Искаш да управляваш оригиналния обект | ✅ Да | ❌ Не — връща нов |