|
|
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
С Новым Годом, уважаемые! Для удобства работы с Lazy-коллекциями использую фильтр OpenSessionInViewFilter. Удобно, мало возни. В предыдущем проекте не возникало ситуации, когда пришлось бы удалять сущность (при удалением клиентом объекта связанная сущность помечалась статусом "удалено", но не удалялась физически из БД). Сейчас такая потребность возникла. Если использую фильтр с параметрами по умолчанию (или с singleSession=true) при попытке удалить сущность возникает ошибка: авторorg.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. Если устанавливаю параметр singleSession в false и пытаюсь удалить объект, вываливается исключение: авторorg.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions Код метода из соответствующего ДАО-класса: Код: plaintext 1. 2. 3. 4. Код: plaintext 1. 2. Что меня удивило, что попытка получить текущую сессию обламывается (при singleSession=false). То есть, если Код: plaintext 1. 2. 3. 4. 5. авторorg.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2011, 17:25 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Вопрос еще более актуальный, чем тогда, когда задавался ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.01.2011, 20:36 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Мспользую OpenSessionInViewFilter в нашем проекте тоже. Его настройки: flushMode - Auto, singleSession = true Удаление, вставка, обновление проходит через транзакционный сервис - т.е реквест доходит до контроллера, тот вызывает какой-то ТРАНЗАКЦИОННЫЙ метод сервиса (который уже юзает ДАО) и все. После отработки метода сервиса все изменения в базе. Еще: DAO - классы наследуй от HibernateDaoSupport(там есть вся логика по получению сессии для данного потока). Если не получается, запости свой проект сюда на форум, попробуем разобрать по косточкам. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 16:22 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
удивила реализация метода удаления. id уникальный или нет? Если это первичный ключ, то удаление можно сделать банально через .delete(new Directions(id)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 16:34 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
IDVsbruckorg.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. Транзации недоконфигурированы в Spring, в основном, потому, что OpenSessionInView не знает какой бизнес метод будет вызван и создает всегда readOnly транзакции. А так как сессия одна на запрос, то и вот. Как вариант, сделать нормальный REST, где POST метод будет соответствовать записи, а GET чтению. Ну и доку почитать что там по конфигурации транзакций c OpenSessionInView можно сделать. IDVsbruckЕсли устанавливаю параметр singleSession в false и пытаюсь удалить объект, вываливается исключение: org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions Коллекция вычитывается в изначальной readOnly транзакции, затем спринг обнаруживает что ему нужна update операция и, вероятно, создаёт под это дело новую сессию. Но тут обнаруживается что Lazy коллекция так просто в двух сессиях не работает. Можно, например, попробовать вычитать коллекцию целиком, задав FetchMode, если она, действительно, нужна вся для корректного удаления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 17:08 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
IDVsbruckЧто меня удивило, что попытка получить текущую сессию обламывается (при singleSession=false). То есть, если авторorg.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here Это тоже легко объяснить. singleSession=false разрешает несколько сессий на запрос. Соответсвенно на поток. Поэтому getCurrentSession() может вернуть вам любую сессию из нескольких созданных в этой обработке запроса. Соответственно Spring запрещает это делать, чтобы исключить недетерминированность. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 17:18 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Ой, дорогой, как же я тебя ждал ... :) Спасибо за ответы. Blazkowiczудивила реализация метода удаления. id уникальный или нет? Если это первичный ключ, то удаление можно сделать банально через .delete(new Directions(id)) Да, первичный. Не понимаю как ... создавать новый конструктор? ... что это даст? - Надо же удалить существующий объект. Одним словом, этот момент я полностью не понял. BlazkowiczТранзации недоконфигурированы в Spring, в основном, потому, что OpenSessionInView не знает какой бизнес метод будет вызван и создает всегда readOnly транзакции. А так как сессия одна на запрос, то и вот. Как вариант, сделать нормальный REST, где POST метод будет соответствовать записи, а GET чтению. Ну и доку почитать что там по конфигурации транзакций c OpenSessionInView можно сделать. А как сделать, чтобы всегда был не readOnly? - На кой он мне? А по умолчанию он всегда readOnly. BlazkowiczКоллекция вычитывается в изначальной readOnly транзакции, затем спринг обнаруживает что ему нужна update операция и, вероятно, создаёт под это дело новую сессию. Но тут обнаруживается что Lazy коллекция так просто в двух сессиях не работает. Можно, например, попробовать вычитать коллекцию целиком, задав FetchMode, если она, действительно, нужна вся для корректного удаления. КАК? Я понимаю как это сделать при селекте, но как это сделать при удалении? Запросом? (хиберовским или нативным) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 17:36 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
IDVsbruckДа, первичный. Не понимаю как ... создавать новый конструктор? ... что это даст? - Надо же удалить существующий объект. Одним словом, этот момент я полностью не понял. Не нужно вычитывать объект по id для того чтобы удалить по id. Даже если он с верятностью 99% находится в кэше второго уровня. Хибернейту нужен только id для удаления. Вот мы и даём ему id в объекте. Значение остальных полей хибернейту не интересно. Открываем JavaDoc http://docs.jboss.org/hibernate/core/3.5/api/ delete - Remove a persistent instance from the datastore. The argument may be an instance associated with the receiving Session or a transient instance with an identifier associated with existing persistent state Открываем мануал http://docs.jboss.org/hibernate/core/3.5/reference/en/html/objectstate.html Transient - an object is transient if it has just been instantiated using the new operator , and it is not associated with a Hibernate Session IDVsbruckА как сделать, чтобы всегда был не readOnly? - На кой он мне? А по умолчанию он всегда readOnly. Тут есть одна фича у Hibernate. Если в не readOnly сессии вычитать сущность и поменять её состояние, то хибернейт отметит её как dirty и вызовет неявный update при коммите. Готов ли ваш код к такому повороту событий? IDVsbruckBlazkowiczКоллекция вычитывается в изначальной readOnly транзакции, затем спринг обнаруживает что ему нужна update операция и, вероятно, создаёт под это дело новую сессию. Но тут обнаруживается что Lazy коллекция так просто в двух сессиях не работает. Можно, например, попробовать вычитать коллекцию целиком, задав FetchMode, если она, действительно, нужна вся для корректного удаления. КАК? Я понимаю как это сделать при селекте, но как это сделать при удалении? Запросом? (хиберовским или нативным) Для начала просто попробуй delete(new Directions(id)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 17:54 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. Что очевидно, так как нет конструктора. Создал конструктор Код: plaintext 1. 2. авторorg.springframework.dao.DataIntegrityViolationException: could not delete: [project.db.pojo.Directions#2]; SQL [delete from directions where id=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [project.db.pojo.Directions#2] И это очень странно, так как Код: plaintext 1. 2. То есть сущность все же надо выбирать перед удалением. Или цепочкой удалять зависимые объекты. Но это точно неправильно, учитывая возможности Хибернейта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 18:18 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Тогда попробуй получить объект через findByCriteria Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 18:34 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Те же яйца ... :( Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 19:22 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
IDVsbruck, таки придется изучить http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 23:27 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Парень, почитай главу про транзакции обязательно. Ты похоже пытаешься все узнать методом научного тыка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.01.2011, 23:35 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Ну, не все ... далеко не все ... Вопросов возникает очень много, но подавляющее количество решаю сам. Даже зачастую и те, которые задавал тут и никто не ответил. В данном случае вариантов 3: сделать как умею (не удалять, а помечать удаленным), сделать через одно место (как, видимо, я и сделаю) или сделать правильно и хорошо с помощью советов. Просто отставить работу и заниматься самообразованием я не буду - времени нет, да и желания особого нет. Был бы это банальный вопрос, он бы тут не задавался. гугл однозначного ответа не дает - везде тоже умники отвечают - "учи или смотри Transactions". Ну не знаю я, где конкретно искать и что искать для данного случая. Все перелопачивать не буду. P.S. В разделах, где я обладаю достаточными знаниями, в случае, если я знаю как сделать или могу помочь, я советую или помагаю. Хотя, бывает, и тыкаю головой, как некоторые ... :), но все равно помагаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2011, 02:16 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
@Transactional(readOnly = false) не? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2011, 11:51 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Странно ... запостил вчера свое решение, а поста нет. Сделал, как и говорил, через одно место: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. @Transactional (со всеми параметрами) я испытал еще до первого поста - это первое, о чем подумал. Для тестов я его втыкал куда только можно - и к бизнес-классу, и к бизнес-методу, и к ДАО-классу, и к методу - его действия не видно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2011, 12:10 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
IDVsbruck@Transactional (со всеми параметрами) я испытал еще до первого поста - это первое, о чем подумал. Для тестов я его втыкал куда только можно - и к бизнес-классу, и к бизнес-методу, и к ДАО-классу, и к методу - его действия не видно. Так мы же не видим всей инфраструктуры. Может у тебя ДАО вообще не в спринговом контексте. Смысл Spring как раз в том чтобы всю эту мишуру не писать в каждом методе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2011, 13:32 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
О! Так и я за это! Не, ДАО-классы в контексте (выдержка из application-config.xml): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. Правда, есть один нюанс ... знаю, что @Transactional вроде как надо ставить в интерфейсе класса, а не в самом классе. И в прошлом проекте эта аннотация так и стояла - в интерфейсе бизнес-класса, по совместительству сервис (он использовался BlazeDS'ом). Сейчас используется DWR, для которого интерфейсы необязательны (такая архитектура приведена даже на родном сайте), поэтому допускаю, что для использования оговариваемой аннотации нужны еще какие-то доработки/настройки. P.S. Приношу извинения за некомпетентное объяснение - теоретическая подготовка у меня никакая. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2011, 14:32 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
IDVsbruck, Как вы решили свою проблему? Ловлю такой же баг - после пересборки проекта с чистого листа . Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. поймал в ht.save(infoReqLog ); Код: java 1. 2. 3. если прописать Код: java 1. 2. то все ок! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 12:35 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Atum1, @Transactional(readOnly=false) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 12:43 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, нет , это уже было испытано :( тут говориться об http://stackoverflow.com/questions/6810158/java-hibernate-write-operations-are-not-allowed-in-read-only-mode Код: java 1. 2. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Плюс еще можно setCheckWriteOperations Код: java 1. 2. работает два варианта - теперь нужно понять какой из них верный :) и разобраться почему такое происходит... PS по поводу mode="aspectj" - тоже задумался, ведь и этот атрибут так же использую .... странно все это .... Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 14:27 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
Atum1нет , это уже было испытано :( Спасибо за комплимент. Вероятно вы предполагали что я, как штатный телепат, это должен был понять уже из первого сообщения. Но для других стоит такие вещи очевидно упоминать в вопросе. Можно было попробовать Propagation указать, чтобы новая или вложеная транзакция создавалсь в сервисе. Atum1 работает два варианта - теперь нужно понять какой из них верный :) Никакой. Open-session-in-view это anti-pattern и вы просто боретесь с одним из косяком, который он породил. Atum1и разобраться почему такое происходит... У Hibernate по-умолчанию Session и Transaction сильно связаны. Вот и выходит что сразу создаётся read-only сессия. Глобально делать все сессии не read-only, тоже как-то не фонтан. Через dirty сущности в Hibernate можно поймать баги с нежелаемыми UPDATE-ами на ровном месте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 14:34 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
BlazkowiczСпасибо за комплимент. Вероятно вы предполагали что я, как штатный телепат, это должен был понять уже из первого сообщения. Но для других стоит такие вещи очевидно упоминать в вопросе. Можно было попробовать Propagation указать, чтобы новая или вложеная транзакция создавалсь в сервисе. Blazkowicz, спасибо Вам! - я сначала попробовал все советы в топике (и @Transactional - так же )- потом стал искать решение. тут немного есть , но не обо всем : http://samolisov.blogspot.ru/2009/01/lazy-loading-hibernate-spring.html Propagation - нужно попробовать ... отпишусь . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 14:38 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
ИМХО, в JavaDoc OpenSessionInViewFilter очень подробно разжевано что как и почему сделано, и как должно работать и какие есть варианты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 14:44 |
|
||
|
OpenSessionInViewFilter блокирует работу с базой
|
|||
|---|---|---|---|
|
#18+
BlazkowiczИМХО, в JavaDoc OpenSessionInViewFilter очень подробно разжевано что как и почему сделано, и как должно работать и какие есть варианты. @Transactional(propagation = Propagation.REQUIRES_NEW) - такое же поведение - и Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. пока работает отлично только с Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2013, 14:54 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38513169&tid=2127907]: |
0ms |
get settings: |
9ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
164ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
52ms |
get tp. blocked users: |
1ms |
| others: | 245ms |
| total: | 494ms |

| 0 / 0 |
