CascadeType.MERGE + Spring Data + Hibernate

 
 
 
Сообщения:47
Привет. Разбираюсь когда конкретно срабатывает CascadeType.MERGE в отношениях между сущностями? Есть две сущности: Contract и Type. Contract владеет Type-ом. Допустим, сработал контроллер, вытянул сущность из базы данных (сопутствующий вопрос - после того как она "вытянулась" ее состояние detach?), одно из полей - type равно null, контроллер "вернул" jsp страничку, на ней отображается какая - то информация, пользователь выбирает значение type, данные снова идут к контроллеру вместе с тем что ввел пользователь. Контроллер снова вытаскивает сущность из бд, ее состояние detach (тот же вопрос - какое у нее состояние? Полагаю, что detach, но почему? Потому что в слое репозитори уже произошла транзакция? из - за этого?). Допустим я работаю с Hibernate, мне надо на сущности Contract вызвать метод setType(Long id), потом вызвать метод merge(contract), который вернет сущность в состояние managed и заперсистит сущность contract, но уже измененную + обновится и соотвествующее значение сущности Type? А если я работаю сo SpringData, то достаточно ли вызова метода save(contract), тоже сработает CascadeType.MERGE?
Изменен:05 дек 2017 15:06
 
 
Сообщения:9640
igor_:
Разбираюсь когда конкретно срабатывает CascadeType.MERGE в отношениях между сущностями?
Когда происходит Session#merge() или EntityManager#merge().
igor_:
Допустим, сработал контроллер, вытянул сущность из базы данных (сопутствующий вопрос - после того как она "вытянулась" ее состояние detach?)
DETACHED сущность становится когда закрывается сессия которая вытащила эту сущность. Или если эта сессия очищается с помощью Session#clear(), Session#evict(). Подобное есть и в EntityManager.

Spring открывает сессию в зависимости от того где ты это настроишь:
- Можно на уровне сервисов ставить @Transactional
- Можно на уровне Servlet Filter добавить OpenSessionInViewFilter
- Или же на уровне Spring MVC interceptor'ом настроить OpenSessionInViewInterceptor.

В любом случае тот кто сессию открыл - тот ее и закроет (даже если через несколько слоев пройдет - например, в случае OSIV Filter + @Transactional откроет и закроет сессию OSIV Filter). И тогда сущности становятся detached.
igor_:
Допустим я работаю с Hibernate, мне надо на сущности Contract вызвать метод setType(Long id), потом вызвать метод merge(contract), который вернет сущность в состояние managed и заперсистит сущность contract, но уже измененную + обновится и соотвествующее значение сущности Type?
merge() делает сохранение того что ему передали, детачит то что ему передали и возвращает новую такую же (ну не тот же объект) сущность уже измененную. Если установлены каскады, то merge() произойдет не только для переданной сущности, но и для ассоциаций. Тогда в результирующем объекте (предполагаю, ибо если честно merge() почти не пользуюсь) ассоциация тоже будет проставлена обновленная.
igor_:
А если я работаю сo SpringData, то достаточно ли вызова метода save(contract), тоже сработает CascadeType.MERGE?
MERGE каскад вызовется на merge(), PERSIST каскад вызовется на save() или persist(), REMOVE каскад вызовется на remove() & delete(), и т.д.

PS: Самое главное в этой ситуации - не использовать Spring Data и прочую автомагию, все (datasource, session factory/entity manager factory, transaction manager, exception translator, aop) настраивать самому. А то так сложно учиться чему либо когда все где-то настроено, но не понятно где и как.
Изменен:05 дек 2017 15:25
 
 
Сообщения:47
Спасибо за ответ, у меня на проекте как раз Spring Data)) буду утюжить книги по Hibernate) Скачал купил Hibernate Quickly. Кстати, я так понял, редко можно увидеть CascadeType.MERGE, так как не очень часто его используют, то есть это исключительный случай, когда транзакция закрывается, в хорошо спроектированной программе предусмотрены транзакции в местах персиста сущности?
Изменен:05 дек 2017 19:15
 
 
Сообщения:9640
Книги которые по-моему стоит читать: POJOs In Action, Java Persistence with Hibernate (именно в таком порядке). Про Hibernate Quickly ничего не знаю..
Изменен:05 дек 2017 19:11
 
 
Сообщения:47
Спасибо, но не хочу читать POJOs In Action))) Кстати, обновил вопрос предыдущий
Изменен:05 дек 2017 19:16
 
 
Сообщения:9640
igor_:
Кстати, я так понял, редко можно увидеть CascadeType.MERGE, так как не очень часто его используют, то есть это исключительный случай, когда транзакция закрывается
Во-первых, не транзакция, а сессия. А во-вторых, не думаю что тут часто речь про закрытие сессии. Скорей про объект который пришел из-вне.
igor_:
Спасибо, но не хочу читать POJOs In Action
Как по мне, так если бы можно было прочесть лишь одну книгу по ORM'ам, то это была бы именно POJOs In Action. Фундаментальная книга.
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет