вставка грааля в БД без сохранения, почему? - PullRequest
1 голос
/ 23 ноября 2011

Я нашел что-то странное в Граалях.

Я создаю объект вроде:

User a = new User()
a.setName("test")
a.save()

после этого я вызываю метод, например setActive вроде:

a.setActive(true)

и НЕ вызывают save (), но они сохраняются в базе данных. Я не знаю почему ?! Я думаю, что это опасно. Есть предложения по этому поводу?

Большое спасибо,

Marco

Ответы [ 3 ]

6 голосов
/ 23 ноября 2011

Grails регистрирует перехватчик OpenSessionInView, который открывает сеанс Hibernate в начале каждого запроса, а также сбрасывает и закрывает его после его завершения.Это в первую очередь для коллекций с отложенной загрузкой.Если бы не было открытого сеанса, после загрузки экземпляра он немедленно отключился бы, поэтому попытка доступа к коллекции вызвала бы исключение.Если сеанс остается активным, коллекции можно разрешать.

По умолчанию Hibernate автоматически отправляет изменения в постоянных экземплярах во время сброса, поэтому, поскольку перехватчик OSIV сбрасывает в конце запроса, любые «грязные» экземпляры, напримерваш экземпляр пользователя будет отправлять свои изменения в базу данных.

Чтобы обойти это, вы можете использовать метод read() для загрузки существующего экземпляра, если вы хотите только временно изменить его, например, для рендеринга вGSP, но не хочу, чтобы изменения автоматически сохранялись.

Это не сработает в вашем случае, поскольку вы не получаете старый экземпляр, вы его создаете.В вашем случае просто позвоните a.discard() после сохранения, и это отключит его от сеанса Hibernate, и Hibernate не будет ничего нажимать, когда происходит сброс.

3 голосов
/ 23 ноября 2011

После выполнения методов обслуживания (в случае транзакции = true) Grails сохраняет все изменения с объектами domain / persist и сбрасывает сеанс гибернации. То же поведение Redirect в действии контроллера.
Чтобы откатить изменения - киньте RuntimeException.

2 голосов
/ 23 ноября 2011

Поскольку Hibernate автоматически сохраняет все ожидающие обновления в постоянных объектах до закрытия сеанса. Так работает Hibernate.

Если вы указываете, что хотите, чтобы объект был постоянным, вызывая .save(), Hibernate предполагает, что вы также хотите, чтобы любые последующие изменения этого объекта были сохранены. Я не вижу смысла в вызове a.setActive(true), если вы не хотите, чтобы это обновление сохранялось.

...