спящий режим обновления постоянных записей - PullRequest
1 голос
/ 01 марта 2011

Мы используем hibernate через язык сценариев на основе java groovy.

Извлекаем запись, обновляем запись и сохраняем запись.

во время обновления мы очищаем ассоциации и перезагружаем их перед сохранением.

Мы получаем исключение, когда Hibernate сбрасывает запись после удаления связей, но перед установкой новых, что вызывает ошибку проверки.

Т.е. у нас есть ограничение на ассоциации: class Entity { ... static constraints = { association1(minSize:1) //require association to have at least 1 record } }

Как лучше всего обновить постоянную запись?

Некоторые потенциальные варианты:

==============================================

[1] создать новую запись и скопировать свойства:

def oldEntity = Entity.findByX(x) if (oldEntity) { oldEntity.properties = newEntity.properties oldEntity.save(flush:true);| } else { newEntity.save(flush:true); }

Проблема здесь в том, что это кажется хакерским - создание отсоединенной сущности и копирование свойств поверх живой.

==============================================

[2] извлечение записи, обновление, сохранение с отключенной очисткой:

sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.MANUAL</p> <p>def existingEntity = Entity.findByX(x) existingEntity.association1.clear() existingEntity.association2.clear()</p> <p>existingEntity.association1.add(new Association(...)) existingEntity.association2.add(new Association(...))</p> <p>sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.AUTO existingEntity.save(flush:true)

Не уверен насчет этого подхода - не нравится такое вмешательство в управление состоянием Hibernate

==============================================

[3] Установите постоянный режим очистки вручную и используйте save () и save (flush: true) для сохранения записей с каскадом: «all-delete-orphan» для обеспечения управления ассоциациями.

Вопрос здесь заключается в том, что это не по умолчанию и зависит от нас, чтобы управлять сбросом Hibernate.

==============================================

Резюме:

Все эти подходы, кажется, пахнут - кто-нибудь может посоветовать наименее плохой подход - или даже наилучшую практику для этой ситуации?

Спасибо

* * Тысяча сорок-девять Alex

Ответы [ 2 ]

1 голос
/ 16 марта 2011

Решение, с которым мы пошли, состоит в том, чтобы установить режим фиксации на «commit», который обновляется только с помощью ручных вызовов entity.save (flush: true) и в конце транзакции, если он не откатывается.

Config.groovy: hibernate.flush.mode="commit"

Мы нашли причуду, что установка этого параметра в DataSource.groovy не работает, хотя это, пожалуй, более очевидное место. Кроме того, новые темы потребовали, чтобы мы установили его вручную - изменение не было выполнено автоматически.

EntityService.groovy: import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH</p> <p>def sessionFactory</p> <p>... sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.parse(CH.config.hibernate.flush.mode.toUpperCase())

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

0 голосов
/ 01 марта 2011

Для меня, если вам действительно нужно очистить и воссоздать эту ассоциацию, второй подход - это тот, у которого меньше запаха.

Нет ничего плохого в установке ручного режима очистки, если вам нужно манипулировать моделью, проходящей через недопустимые состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...