|
|
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Добрый день, есть задача: Открываю сессию с hibernate, начинаю транзакцию, создаю 2 объекта и делаю им save. session = factory.openSession(); session.setFlushMode(FlushMode.MANUAL); session.beginTransaction(); MObject obj1 = new MObject(); MObject obj2 = new MObject(); session.saveOrUpdate(obj1); session.saveOrUpdate(obj2); Далее мне бы очень бы хотелось сразу получить этих 2 сохраненных объекта запросом: List list = session.createQuery("from Mobject").list(); как результат лист не содержит данных ну или вновь добавленных объектов. Уточню, что мне по задаче нельзя до запроса сделать автоматический или ручной сброс данных в базу( session.flush(); ). Возникают следующие вопросы: можно ли в данном случаи получить запросом объекты которые созданы и находятся в памяти сессии без сброса их в базу? Если можно, то как? Ну или возможно есть какие-то хитрые пути для того чтоб их получить из сессии, по идентификатору дергать нельзя. А также сопутствующий вопрос, а если наоборот я удалю из выборки 2 объекта, как сделать так чтоб при новом запросе, они не попали в эту выборку? Заранее благодарен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 02:31:11 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyУточню, что мне по задаче нельзя до запроса сделать автоматический или ручной сброс данных в базу(session.flush();).Вот отсюда ноги проблемы и растут. Почему нельзя? Дело в том, что у вас сначала MObject'ы сначала сохраняются в кеше первого уровня, а отправляя запрос вы его обходите - там работает уже Query Cache. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:12:00 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Нельзя потому что используется «долгая» операция(диалоги) с открытой сессией hibernate между запросами от пользователя, в конце запроса session.disconnect() в начале следующего session.reconnect() чтобы не держать jdbc соединение. Ну и по завершению диалога либо session.flush() либо откат Поэтому сбрасывать в базу не могу ибо потом все эти действия могут быть отменены. А вот в процессе работы видеть предварительно добавленные объекты при последующей выборки в этой же сессии или наоборот если что-то было удалено из выборки, а затем снова сделали запрос, то следовательно не получать эти объекты в список мне как раз и надо. Может можно это как-то на кэше запросов сделать или еще каким-нибудь способом? Просто очень не хочется изобретать велосипед, ну а если и изобретать то хоть по правильному с надеждой на стабильную и быструю работу в дальнейшем) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:27:43 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyПоэтому сбрасывать в базу не могу ибо потом все эти действия могут быть отменены. противоречие. Выберите 2 модели в хибере: - длинные транзакции - пишите в БД и никто до коммита не увидит ваше творчество. В конце дня сделаете rollback - короткие... Я так понял что у вас п.1? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:32:50 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyПоэтому сбрасывать в базу не могу ибо потом все эти действия могут быть отменены. противоречие. Выберите 2 модели в хибере: - длинные транзакции - пишите в БД и никто до коммита не увидит ваше творчество. В конце дня сделаете rollback - короткие... Я так понял что у вас п.1? Хм....насколько я понимаю как раз держать длинную транзакцию в многопользовательском приложении ну очень накладно и вредно. Поэтому я держу открытой сессию, на время простоя пока пользователь набивает данные хочу отпускать соединение сессии с jdbc путем session.disconnect(). когда пользователь вносит очередную правку я подключаю сессию с помощью реконекта, открываю транзакцию выполняю действия и закрываю транзакци. и снова отключаю сессию. Но при всем этом не сбрасываю данные из сессии в саму БД. Проблема встает в том, что пользователь к примеру добавил 2 новых объекта в список, затем нажал кнопку «обновить» список по которой выполняется выборка и новые добавленные объекты естественно не появились. Хотя они дабавлены и сессия о них знает. Тут я упрощенно конечно пример привел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:42:09 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyи снова отключаю сессию. Но при всем этом не сбрасываю данные из сессии в саму БД. ну и почему не отправить в БД в конце РАБОТЫ, т.е. окончания БИЗНЕС-транзакции? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:50:09 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyХм....насколько я понимаю как раз держать длинную транзакцию в многопользовательском приложении ну очень накладно и вредно вредно курить, но есть ньюансы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:50:45 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
ещё вариант отключить 2-ой кэш. Т.к. он не всегда нужен. (вам виднее) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:51:57 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Простой пример: есть заказчик есть заказы, пользователь открыл форму с конкретным заказчиком, форма из 2х вкладок. На первой инфа по заказчику, на второй список его заказов. Список заказов к примеру большой и выгружается постранично(по 20 заказов за раз). Так вот пользователь к примеру удалил пару заказов ненужных, а 1 новый добавил, загрузил вторую порцию заказов(следующие 20), потом вернулся к первой, а ничего не изменилось для него, то есть в списке снова присутствуют удаленные заказы и нет добавленных. В самой сессии то данные об этом есть и при сбросе в базу(конечное подтверждение операции), все запишется, но на внешний вид пользователю кажется, что система не работает. Контролировать это руками даже не знаю как правильно, так как надо сделать универсальный метод работы для всех подобных форм и объектов в системе. Хотелось чтобы по максимальному все было бы автоматически, ну или какое-то хитрое решение данной задачи придумать. насчет кэша второго уровня не совсем понял, он у меня и не включен..... насчет вреда 1 большой транзакции...редактирование может и часы занимать и насколько я понимаю это очень сильно ударит по нагрузке, когда одновременно работающих пользователей будет не 10 и не 100. а по требованию которые мне выставлены, нужно сделать с учетом что их будет в разы больше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 10:58:15 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyХотелось чтобы по максимальному все было бы автоматически 2 варианта: - найти точно такую тему, там решение svenom с каскадами - режим длинных транзакции (меньше писанины, до ~ 1000 - 10000 клиентов) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:04:31 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyи снова отключаю сессию. Но при всем этом не сбрасываю данные из сессии в саму БД. ну и почему не отправить в БД в конце РАБОТЫ, т.е. окончания БИЗНЕС-транзакции? потому что работа будет закончена после редактирования всех нужных данных, я привел пример формы из 2х вкладок в реале их сейчас уже бывает под 6 штук и эта бизнес операция реально может занимать часы, причем в самом конце пользователь может передумать и нажать откат всей операции. если сохранять промежуточные данные в базу все время то надо как-то помечать объекты, что "временные" пока не подтвердили операцию окончательно, другим пользователям не давать их читать как будто их нет(а значит все выборки дополнят условиями), сборщик мусора и все дела...много гемора, хотелось бы все сделать не так жестко ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:06:03 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyХотелось чтобы по максимальному все было бы автоматически 2 варианта: - найти точно такую тему, там решение svenom с каскадами - режим длинных транзакции (меньше писанины, до ~ 1000 - 10000 клиентов) не совсем понимаю причем тут каскады? ведь вполне может быть так что именно "заказчик" не будет иметь OneToMany на заказы, а заказы односторонне будут иметь ManyToOne. а что там еще было в той теме, чтоб было легче найти? а есть какие-нибудь данные по нагрузке при длинных транзакций, к примеру это же будет в пуле открыто очень много соединений с базой(столько сколько параллельно пользователей ведет работу с такими формами), а каждое из них жрет память, даже с оперативкой встанут вопросы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:10:23 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyPetro123пропущено... ну и почему не отправить в БД в конце РАБОТЫ, т.е. окончания БИЗНЕС-транзакции? потому что работа будет закончена после редактирования всех нужных данных, я привел пример формы из 2х вкладок в реале их сейчас уже бывает под 6 штук и эта бизнес операция реально может занимать часы, причем в самом конце пользователь может передумать и нажать откат всей операции. ===== вы не поняли. Бизнес-транзакция\Хибер\БД-транцакции - это всё разные вещи. Бизнес, это кнопка у пользователя либо крест на форме. если сохранять промежуточные данные в базу все время то надо как-то помечать объекты, что "временные" пока не подтвердили операцию окончательно, другим пользователям не давать их читать как будто их нет(а значит все выборки дополнят условиями), сборщик мусора и все дела...много гемора, хотелось бы все сделать не так жестко ======= при длинных НИЧЕГО этого не надо. Следит БД и его уровень изоляции транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:13:25 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyа что там еще было в той теме, чтоб было легче найти? свою же тему? ЭТО твоя тема "интересная задача" :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:17:41 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
при длинных транзакциях, я понимаю все будет работать, но пугает сколько потребуется ресурсов, просто через какое-то время уже работы системы увидеть, что она жутко тормозит будет очень не приятно, возможно я конечно ошибаюсь насчет затраченных ресурсов.. просто смотрю вот на процессы, пул держит сейчас 15 открытых коннектов к БД, каждый из них жрет памяти по 300 мегабайт, а если открыто сразу 10000??? про тему, скорее всего я понял о какой вы говорите, я наверно ее и задавал перед отпуском, я оттуда подчерпнул для себя, но не все...вот проблема с добавляемыми элементами как я выше писал осталась) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:22:02 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyа что там еще было в той теме, чтоб было легче найти? свою же тему? ЭТО твоя тема "интересная задача" :)) ага, уже увидел))) я оттуда уже взял пару подходов, ушел в отпуск, сейчас вернулся и вот с добавляемыми элементами столкнулся) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:23:00 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyага, уже увидел))) вот народ, мусолят одну тему - потом во второй по новой, причём без ссылок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:28:20 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom писал что: "Если вы делаете SELECT/DELETE/SELECT в рамках одной сессии, то Хибер все сделает за вас автоматом." а если SELECT/SAVE/SELECT в рамках одной сессии, такое не получится? именно в этом и стоит мой главный вопрос с учетом того что заказчик "заказчик" не будет иметь OneToMany на заказы, а заказы односторонне будут иметь ManyToOne. Большое спасибо вам за ответы, в прошлой теме многое для себя узнал и в этой узнаю, еще раз спасибо!!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:31:04 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyага, уже увидел))) вот народ, мусолят одну тему - потом во второй по новой, причём без ссылок. да что-то не подумал, видать после НГ праздников голова думать еще не начала) извиняюсь ссылка: /topic/905874&hl= ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 11:32:36 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, Удачи! Код: 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. 29. 30. 31. 32. 33. 34. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 12:08:31 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slippery, Удачи! Код: 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. 29. 30. 31. 32. 33. 34. насколько я понял по документации есть и 3 путь! "Кроме того, вы можете предпочесть использовать одну сессию, которая охватывает несколько запросов вашей транзакции приложения. В этом случае, вам не нужно беспокоиться о присоединении несвязанных объектов, так как объекты остаются хранимыми в рамках одной длительной сессии Сессия сериализуемая и может быть безопасно сохранена, например, в сервлете HttpSession. Конечно, базовое JDBC соединение должно быть закрыто и новое соединение должно быть получено на следующий запрос. Вы используете методы disconnect() и reconnect() интерфейса сессии для того, чтобы освободить соединение и затем получать новое соединение. Такое подход известен, как сессия-на-транзакцию-приложения или длинная сессия." Вот именно 3 вариант меня и привлек, а какие тут минусы. Да естественно объект заказчик мы блокируем при редактировании. НО вот заказы блокировать уже не надо. Так вот именно в этом 3 варианте будут ли работать: 1) SELECT/DELETE/SELECT в рамках одной сессии? 2) SELECT/SAVE/SELECT в рамках одной сессии? первое проверить не успел, еще не был за компом где есть проект, а вот второе не работает, либо я не так это делаю....именно в этих двух вопросах и заключается моя проблема. Да может если кто пробовал реализовывать 2(новую сессию и присоединять объекты) или 3(1 сессия которой делают коннект-реконет) вариант может сразу сказать какой лучше и чем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 16:44:21 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
авторПоэтому сбрасывать в базу не могу ибо потом все эти действия могут быть отменены. flush не комитит транзакцию. Делайте flush, а если надо будет отменить изменения, то вы всегда можете сделать rollback. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 20:52:38 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
С первого раза неправильно понял вопрос, поэтому предыдущее сообщение недействительно. Сейчас вникну еще раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2012, 20:55:47 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyДа естественно объект заказчик мы блокируем при редактировании. НО вот заказы блокировать уже не надо это почему? Отдели БЛ от технической части. ВИ (прецендент): - бизнес-транзакция начинается с момента НЕ показа на экране Заказчик - его заказы, а на кнопку Редактировать. - заканчивается - крест\Сохранить\Отмена - при лог.блокировке, ты должен известить второго чела, что Иванов УЖЕ взял ДОКУМЕНТ заказчика на редактирование при Нажатии Петровым на кн. Редактировать. Если не блокировать заказы, то 2-3-10 менеджеров будут удалять один и тот же заказ № 15 у Заказчика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 09:50:48 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
хотя ты наверно имел ввиду - по БЛ блокируется ВСЯ информация ограниченная кнопкой Редактировать, а технически это можно сделать Одной блокировкой заказчика. Тогда ОК ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 09:54:36 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
2/ если ты не пойдёшь по методу 2, то как ты будешь присоединять к транзакции отложенную подгрузку объектов? Ты же не всё на вкладках будешь грузить на первый рендеринг страницы? Типа AJAX? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 09:58:48 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123хотя ты наверно имел ввиду - по БЛ блокируется ВСЯ информация ограниченная кнопкой Редактировать, а технически это можно сделать Одной блокировкой заказчика. Тогда ОК да именно это я и имел ввиду, но вопрос остается открытым, то есть сделав так: MObject obj1 = new MObject(); MObject obj2 = new MObject(); session.saveOrUpdate(obj1); session.saveOrUpdate(obj2); а потом вот так List list = session.createQuery("from Mobject").list(); я не получу 2 дабавленных объекта, то есть 2 добавленных заказа и аналогично если я удалю пару заказов из списка и снова запрошу список заказов, то удаленные заказы снова придут в результат. Так вот как можно сделать так, чтоб удаленные в этой сессии заказы не попадали в выборку??? Ну и как чтоб попадали добавленные? Сейчас это главная проблема для меня, которую я не знаю как оптимально решить.......очень жду советов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 11:55:05 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro1232/ если ты не пойдёшь по методу 2, то как ты будешь присоединять к транзакции отложенную подгрузку объектов? Ты же не всё на вкладках будешь грузить на первый рендеринг страницы? Типа AJAX? так объект в сессии, а сессия не закрывается, я начинаю новую транзакцию и дергаю у этого объекта лази поле и все и в конце закрываю транзакцию. Или если мне еще нужны данные то просто тоже в этой же сессии открываю транзакцию подгружаю данные которые попадают в сессию и закрываю транзакцию. Делаю я это при следующих обращениях к другим вкладкам, это в теории я еще не все успел попробовать. Или я не так понял вопроса? меня сейчас более волнует как решить вопросы заданные мной в предыдущем посту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 11:59:09 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Еще раз - запрос на то и запрос, что бы быть отправленным в БД. Есть в БД записей нету, то вы никак не можете их вернуть через запрос. Никак. Надо делать flush(), точка. Если flush() делать нельзя, ок - тогда пересматривайте свой подход в целом, так как ваша проблема звучит уж очень надуманной и высосанной из пальца. Опишите подробнее решаемую задачу - постараемся что-нибудь посоветовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:05:09 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, разве при выкл. 2 кэше нужно делать session.flush? Сброс в БД не автоматом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:36:01 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123svenom, разве при выкл. 2 кэше нужно делать session.flush? session.flush() сбрасывает кэш 1го уровня - саму сессию. кэш второго уровня к этому отношения не имеет. Petro123Сброс в БД не автоматом? Это отдельная фича. Если понять персистент объект в транзакции, то при коммите транзакции хибер сохранит состояние в БД автоматом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:40:55 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, ок. Самый простой вариант: - session.flush - закрыть сессию Без ОБОИХ строк в БД будет пусто? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:48:33 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
я просто думал, что 1 уровень всегда синхрон с БД, если общаться исключ. через хибер. Типо автокоммита. ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:50:04 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
В общем, понял я вашу проблему. Есть два решения. Одно умное, правильное, но геморное. Второе топорное, кривое, но быстрее. Изначально проблема заключается в том, что вы пытаетесь переложить на сессию Хибера то, для чего она не предназначена. А именно - поддержание состояния работы пользователя между запросами. Так вот, этим должна заниматься не сессия Хибера, а сессия сервелета, а логика поддержания этого состояния должна поддерживаться вами вручную. 1) Правильное решение - писать код самому, который будет отслеживать изменения пользователя. Это будут скорее всего тупо POJO с минимумом логики и в основном геттерами - сеттерами. В итоге - для всех операций пользователя вы будете только считывать данные из БД, то есть открыли сессию Хибера, быстро считали, закрыли. И лишь последним действием - сохранением - вы переносите все изменения из сессии сервлета в сессию Хибера и комитите их. 2) Дерьмовое решение - полезть в непубличный API Хибера. То есть берете сессию, кастите ее до SessionImpl и начинаете копаться в потрохах Хибера. Примеры: а) вызвать sessionImpl.gtPersistenceContext() и порыться там; б) вызвать sessionImpl.getActionQueue(), потом через рефлекшн получить значения закрытых полей insertions/deleteions/updates и что-нибудь замутить с ними; в) вызвать sessionImpl.getListeners() и выставить своих листенеров на события. Но учтите, что пойдя вторым путем, вы испортите свою карму, совершив акт говнокодерства. Еще несколько таких проступков - и бессмертный дух говнокодерства поработит вас ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:57:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123я просто думал, что 1 уровень всегда синхрон с БД, если общаться исключ. через хибер. Типо автокоммита. ?Это настриваемо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 12:57:59 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123 Самый простой вариант: - session.flush - закрыть сессию Без ОБОИХ строк в БД будет пусто? Зависит от управления транзакциями. В нормальном случае ничего делать не нужно. Вот пример апдейт метода: Код: java 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 13:08:16 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Аффтар держись. Счас у тебя будет куча решений.:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 13:37:55 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom мы пока отвлеклись от вопроса. Если будем писать так много, то будет опять флейм "как хранить состояние с ОРМ" :) BlazkowiczВ нормальном случае ничего делать не нужно я тоже про это. 1 кэш это технический кэш. Он не может быть рассогласован. Вопрос: - кто даст пример и - почему выше код не работает? ЗЫ. там нет старт транзакции, но думаю это не нужно пока? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:23:18 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123 , Причина проблемы озвучена выше, решение озвучено выше. Читайте внимательнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:32:23 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
OK svenomЭто настриваемо. уточни, если не трудно, где и как Аффтар ! твой код не работает в одной сессии хибера? Т.е. сделай пример с "Session-Per-Request" Одна сессия хибера на одну реквеста. Несколько реквестов (состояние) потом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:38:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123OK svenomЭто настриваемо. уточни, если не трудно, где и как session.setFlushMode(FlushMode.???); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:43:57 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, лучше так: авторбольшинству приложений редко нужно указывать flush() явно.... FlushMode.AUTO – по умолчанию. с этим Flush выяснили - указывать не надо (пока) Вопрос про код выше остался. ______________________________________________ "Сделай настолько просто, насколько это возможно, но не проще". © А. Эйнштейн. AutoPOI.ru — ГИС-технологии для Oracle ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:52:14 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Сформулируйте вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:52:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123Вопрос: - кто даст пример для одной сессии и - почему выше код автора не работает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 14:54:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
1. Пример чего надо привести? 2. Пример автора не работает, так как информация об удаленных/сохраненных объектах находится в кеше первого уровня и не был выполнен flush(), а HQL запрос лезет напрямую в базу, минуя кеш первого уровня. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:01:10 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom1. Пример чего надо привести? ==== рабочий пример с настройками по умолчанию. Желательно без flush 2. Пример автора не работает, так как информация об удаленных/сохраненных объектах находится в кеше первого уровня и не был выполнен flush(), а HQL запрос лезет напрямую в базу, минуя кеш первого уровня. ===== покажите как лезть не в БД, а оперативку ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:05:24 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123===== покажите как лезть не в БД, а оперативку [/quot] new HashSet(list).put(obj1); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:12:17 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, ммммм. вы профи, но вы так кратки ) Как вставить объект в сессию и прочитать из сессии-оперативы? Или добавьте свой код к коду автора? session.saveOrUpdate(obj2); опять достать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:18:24 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123session.saveOrUpdate(obj2); опять достать? Не поверишь. session.get() вернет obj2 без сбрасывания всего кэша в базу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:25:49 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Вообще складывается впечатление, что автор из ORM пытается получить функциональность Detached Data Set. Хибернейт не умеет рабоать в оффлайне, накапливая изменения, чтобы потом их все сбросить. Если для каких-либо операций ему нужно будет получить акутальное состояние из базы, он сам сессию зафлашит, без явного вызова session.flush() Поэтому если изменения надо накапливать, это стоит делать отдельным инструментом а не самой сессией. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:29:49 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, отлично! Я тоже нашёл на твоём форуме - find () и авторА>Здравствуйте! А>Помогите разобраться с проблемой: А>есть метод А>@Transactional А>public XXX save(XXX xxx) { А> if (xxx.id != 0) { А> //надо прочитать этот же объект из базы А> XXX oldXXX = load(xxx.id); А> //опс!!!!!!! А> Assert.isFalse(xxx.equal(oldXXX)); А> } А>} А>@Transactional(propagation = Propagation.SUPPORTS) А>public load(int id) { А> //тупо селект А>} А>[/java] 1. flush before/after load 2. new InitialContext().lookup("jdbc/MyConn") ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:31:04 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Blazkowiczполучить функциональность Detached Data Se именно! Я просто не хочу пока холивар. Есть некоторые мысли. Сначала с ЕГО кодом разобраться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:32:35 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Аффтар!!! алё ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:33:10 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123 Сначала с ЕГО кодом разобраться. Уже разобрались. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:34:19 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomPetro123 Сначала с ЕГО кодом разобраться. Уже разобрались. цыц... :) ты не автор, и у меня был вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:36:03 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123svenom2. Пример автора не работает, так как информация об удаленных/сохраненных объектах находится в кеше первого уровня и не был выполнен flush(), а HQL запрос лезет напрямую в базу, минуя кеш первого уровня. ===== покажите как лезть не в БД, а оперативку Через кеш первого уровня и HQL запрос - никак. Вообще никак. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:49:39 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
предложение - подвопрос топика "несколько сессий и состояние" тут Флейм для пользы - Как хранить Состояние в 3-х звенке или Есть ли SpringСостояние? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 15:53:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomВ общем, понял я вашу проблему. Есть два решения. Одно умное, правильное, но геморное. Второе топорное, кривое, но быстрее. Изначально проблема заключается в том, что вы пытаетесь переложить на сессию Хибера то, для чего она не предназначена. А именно - поддержание состояния работы пользователя между запросами. Так вот, этим должна заниматься не сессия Хибера, а сессия сервелета, а логика поддержания этого состояния должна поддерживаться вами вручную. 1) Правильное решение - писать код самому, который будет отслеживать изменения пользователя. Это будут скорее всего тупо POJO с минимумом логики и в основном геттерами - сеттерами. В итоге - для всех операций пользователя вы будете только считывать данные из БД, то есть открыли сессию Хибера, быстро считали, закрыли. И лишь последним действием - сохранением - вы переносите все изменения из сессии сервлета в сессию Хибера и комитите их. 2) Дерьмовое решение - полезть в непубличный API Хибера. То есть берете сессию, кастите ее до SessionImpl и начинаете копаться в потрохах Хибера. Примеры: а) вызвать sessionImpl.gtPersistenceContext() и порыться там; б) вызвать sessionImpl.getActionQueue(), потом через рефлекшн получить значения закрытых полей insertions/deleteions/updates и что-нибудь замутить с ними; в) вызвать sessionImpl.getListeners() и выставить своих листенеров на события. Но учтите, что пойдя вторым путем, вы испортите свою карму, совершив акт говнокодерства. Еще несколько таких проступков - и бессмертный дух говнокодерства поработит вас Автор тут) спасибо, svenom 1. Сессия хранит все что мы наделали если ее не закрывать, и в конце при ручном сбросе сохранит все изменения в бд. Так же уже проверил, что если к примеру я сделал выборку какого то элемента, так: get(A.class, 1); исправил в нем какое-то поле и после сделал так: createQuery("from A").list(); то в результате в списке объектов А будет объект с ид-1 с уже измененным значением поле. То есть хибер заменил объект из выборки на тот что хранится в памяти ну или смержил, внутренностей не знаю. Я надеялся, что также автоматически хибер сможет убрать и уже удаленные объекты, которые содержатся в сессии со статусом DELETE, то есть если бы я удалил объект А с ид-1: A a= get(A.class, 1); remove(a); createQuery("from A").list() то в выборке его уже небыло бы, но увы, он там есть.... 2. если идти по первому варианту, мне придется к примеру в мапе хранить все измененные(добавленные, удаленные, update-сам хибер контролирует судя по эксперименту) объекты, передавать мап между вкладками. В моем случаи пихать мап в сессию не нужно так как: используется zkoss, создается страница и ее контроллер, на страницу помещается компонент типа таббокса в котором и будут вкладки. Вкладки являются отдельными компонентами и помещаться в таббокс будут при создании страницы в зависимости от рассматриваемого объекта. ZKOSS сам поддерживает состояние объекта-контроллера в памяти для запросов от элементов находящихся на странице, то есть если я в контроллере укажу атрибутом какое-то поле, а потом на разных вкладках таббокса будут щелкать кнопки посылающие контроллеру запросы, то класс контроллера будет один и тот же и атрибут с указанным значением будет один и тот же и доступен всем компонентам(в данном случаи вкладкам). Поэтому мап, сессию или что-там еще могу хранить как атрибуты контроллера(каркаса/визарда) на котором и будут располагаться вкладки. Далее мне видимо придется при удалении или добавлении объекта на любой из вкладок, помещать его в этот мап . Ну, а далее мне придется фильтровать все выборки на вкладках руками, то есть получаем на какой-то вкладке createQuery("from A").list() и проверяем есть ли объекты типа А в мапе , ага есть, тогда фильтруем выборку, удалим те, что удалены и добавим тех что нет. Правильно ли я понял вашу идею? Если да, то тут минусы, ладно фильтровать удаленные объекты еще логично и понятно как, но вот добавлять которых нет, уже не совсем ясно, ведь запросы могли быть по условиям, а не простой селект всех из списка, а если по условии то не факт, что в результат выборки нужно добавить все новые объекты получаемого типа из мапа , может быть только половина подходит. к примеру на первой вкладке добавили двух пользователей с именами Петя, Вася. А на второй делаем запрос "найти всех пользователей чье имя начинается на П" тогда в эту выборку нужно добавить только 1 пользователя из мапа , а не двух. Как быть в таком случаи???? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 16:48:43 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Еще раз уточню, что вкладки будут делать разные программисты, которым вникать в тонкости не нужно, для них весь механизм должен быть по возможности прозрачен. И еще может у кого-нить есть хоть какие-то данные если использовать 1 большую транзакцию для решения этой проблемы. Насколько это "положит" систему если таких транзакций будет открыто параллельно ну к примеру 1000 или даже 10000??? Судя по тому сколько отжирет по памяти соединение с бд хранимое в пуле, мне становится страшно, вот почему долгие именно транзакции я не рассматривал, но возможно я не прав??? но вот открываю htop процессы, ит каждый коннект к базе(у меня постгри) это отдельный процесс и жерт он по 300 метров, сейчас штук 10 в пуле...а если их будет 10000 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 16:58:50 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Вот теперь вроде полностью описана задача с её проблемами, может кто-то решал нечто такое или идеи есть интересные как можно такое решить?) на всякий случай еще раз скопирую описание задачи: реализовать универсальный визард(карточку) для работы со всеми объектами системы. Для каждого объекта будут разные наборы закладок и определяться в зависимости от того какие интерфейсы реализует объект, для разных объектов могут использоваться одинаковые закладки, ну к примеру если объекты входят в систему безопасности, то для таких объектов будет вкладка «доступ». Переключения между вкладками может быть в произвольном порядке, а не в строгом, как у настоящего визарда. Все изменения, что в нес пользователь на всех закладках в итоге нужно сохранить в базу в 1 транзакции предположительно последней. Создания вкладок по редактированию логически связанных объектов должны быть реализованы независимо друг от друга и прямой передачи данных между ними быть не должно. Данные созданные на закладке с номером 1 должны быть видны(доступны) на закладке 2, причем закладка 2 разрабатывается с незнанием о закладки 1, поэтому данные должны выниматься для разработчика прозрачно к примеру через hql запрос, дополнительные варианты рассматриваются. То есть если на закладки 1 добавили пользователя, а на 2 закладки нужно работать с существующими пользователями, то пользователь добавленный на закладке 1 должен присутствовать в выборке полученной на второй закладке. Выборки на второй закладки будут с условиями, поэтому пользователи добавленные на закладки один попадают в выборку на закладке 2, если соотвествуют указанным условиям выборки. Данные добавляемые на всех закладках не доступны другими пользователям или другим визардам, то есть если мы добавили какого-то пользователя, но не провели заключительного "комита" то этот пользователь не должен попадать в выборки в системе, кроме выборок того же визарда в котором пользователь добавлен ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:09:19 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Задача решается только через длинные транзакции. Как делать длинные транзакции в вебе, я не знаю. В соседнем треде svenom говорил, что для него это не проблема, может он вам поможет. Я бы на вашем месте переработал ui. ит каждый коннект к базе(у меня постгри) это отдельный процесс и жерт он по 300 метров, сейчас штук 10 в пуле...а если их будет 10000 Какие у вас значения work_mem и shared_buffers? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:20:27 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪЗадача решается только через длинные транзакции. Как делать длинные транзакции в вебе, я не знаю. В соседнем треде svenom говорил, что для него это не проблема, может он вам поможет. Я бы на вашем месте переработал ui. ит каждый коннект к базе(у меня постгри) это отдельный процесс и жерт он по 300 метров, сейчас штук 10 в пуле...а если их будет 10000 Какие у вас значения work_mem и shared_buffers? USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command postgres 20 0 101M 3736 1648 S 0.0 0.1 0:00.01 | `- postgres: 127.0.0.1(49534) idle и вот таких сейчас штук 10, но для каждой долго транзакции будет же свой процесс открыт ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:27:29 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyто в выборке его уже небыло бы, но увы, он там есть.... фигово. Я так понял, это 1 кэш не синхро автоматом с БД? А если руками flush? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:32:55 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyит каждый коннект к базе(у меня постгри) это отдельный процесс и жерт он по 300 метров задай вопрос в субд - imho это ненормально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:34:53 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪЗадача решается только через длинные транзакции. Как делать длинные транзакции в вебе, я не знаю. В соседнем треде svenom говорил, что для него это не проблема, может он вам поможет. Я бы на вашем месте переработал ui. ит каждый коннект к базе(у меня постгри) это отдельный процесс и жерт он по 300 метров, сейчас штук 10 в пуле...а если их будет 10000 Какие у вас значения work_mem и shared_buffers?Неверно, длинные транзакции тут не нужны, именно про это я и говорю. Автор , вам отвечу вечером, тут надо просто много писать, сейчас времени на это нет. Ну то есть пофлеймить маленькими постами могу, а вот вдумчиво написать - попозже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:36:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyто в выборке его уже небыло бы, но увы, он там есть.... фигово. Я так понял, это 1 кэш не синхро автоматом с БД? А если руками flush? нет, я имел ввиду что в выборке он есть в моем случаи, когда я специально не делаю flush перед след запросом, мне по моей задаче нельзя его делать, мне его можно сделать только в самом конце, отсюда и проблема. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:38:14 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomЙуный джавистЪЗадача решается только через длинные транзакции. Как делать длинные транзакции в вебе, я не знаю. В соседнем треде svenom говорил, что для него это не проблема, может он вам поможет. Я бы на вашем месте переработал ui. пропущено... Какие у вас значения work_mem и shared_buffers?Неверно, длинные транзакции тут не нужны, именно про это я и говорю. Автор , вам отвечу вечером, тут надо просто много писать, сейчас времени на это нет. Ну то есть пофлеймить маленькими постами могу, а вот вдумчиво написать - попозже. спасибо, жду с нетерпением большого и вдумчивого совета ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2012, 17:39:29 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery1. Сессия хранит все что мы наделали если ее не закрывать, и в конце при ручном сбросе сохранит все изменения в бд. Так же уже проверил, что если к примеру я сделал выборку какого то элемента, так: get(A.class, 1); исправил в нем какое-то поле и после сделал так: createQuery("from A").list(); то в результате в списке объектов А будет объект с ид-1 с уже измененным значением поле. То есть хибер заменил объект из выборки на тот что хранится в памяти ну или смержил, внутренностей не знаю. Я надеялся, что также автоматически хибер сможет убрать и уже удаленные объекты, которые содержатся в сессии со статусом DELETE, то есть если бы я удалил объект А с ид-1: A a= get(A.class, 1); remove(a); createQuery("from A").list() то в выборке его уже небыло бы, но увы, он там есть....Итак. Тут расскажу только про рабоут сессий. По решению вашей проблемы ниже. Есть кеш первого уровня. Его скоуп - сессия. В него кладутся все объекты, с которыми вы работали - все, что создали и сохранили, все что вытащили черезе запрос или через load/get. Теперь внимание - все HQL/SQL запросы, все критерии - НЕ ИДУТ через кэш первого уровня, они в него не смотрят . Они вытаскивают инормацию сразу из БД и только потом кладут ее в кеш. Поэтому, если вы что-то создали, но не сделали flush(), то нет никакого способа заставить ХИбер вытащить это через HQL запрос. Вообще никак. slippery2. если идти по первому варианту, мне придется к примеру в мапе хранить все измененные(добавленные, удаленные, update-сам хибер контролирует судя по эксперименту) объекты, передавать мап между вкладками. В моем случаи пихать мап в сессию не нужно так как: используется zkoss, создается страница и ее контроллер, на страницу помещается компонент типа таббокса в котором и будут вкладки. Вкладки являются отдельными компонентами и помещаться в таббокс будут при создании страницы в зависимости от рассматриваемого объекта. ZKOSS сам поддерживает состояние объекта-контроллера в памяти для запросов от элементов находящихся на странице, то есть если я в контроллере укажу атрибутом какое-то поле, а потом на разных вкладках таббокса будут щелкать кнопки посылающие контроллеру запросы, то класс контроллера будет один и тот же и атрибут с указанным значением будет один и тот же и доступен всем компонентам(в данном случаи вкладкам). Поэтому мап, сессию или что-там еще могу хранить как атрибуты контроллера(каркаса/визарда) на котором и будут располагаться вкладки. Далее мне видимо придется при удалении или добавлении объекта на любой из вкладок, помещать его в этот мап . Ну, а далее мне придется фильтровать все выборки на вкладках руками, то есть получаем на какой-то вкладке createQuery("from A").list() и проверяем есть ли объекты типа А в мапе , ага есть, тогда фильтруем выборку, удалим те, что удалены и добавим тех что нет. Правильно ли я понял вашу идею? Если да, то тут минусы, ладно фильтровать удаленные объекты еще логично и понятно как, но вот добавлять которых нет, уже не совсем ясно, ведь запросы могли быть по условиям, а не простой селект всех из списка, а если по условии то не факт, что в результат выборки нужно добавить все новые объекты получаемого типа из мапа , может быть только половина подходит. к примеру на первой вкладке добавили двух пользователей с именами Петя, Вася. А на второй делаем запрос "найти всех пользователей чье имя начинается на П" тогда в эту выборку нужно добавить только 1 пользователя из мапа , а не двух. Как быть в таком случаи????В общем случае в приложении есть слой работы с БД - DAL, есть доменная модель - это часто тупо Entity-бины, есть сервисный слой - это либо те же Entity-бины (Rich Domain Model), либо это отдельные объекты (напр, EJB), которые оперируют над объектами доменной модели. И, наконец, есть слой презентации. Так вот, в общем случае слой презентации не видит доменную модель, он не видит сущностей, он общается с сервисным слоем через определенный интерфейс и получают от него не сущности, а DTO - data transfer object. DTO - это специальные объекты, которые используются только для того, что бы быть переданы клиенты, все. Итого, мы получаем такую схему: [СУБД] - [DAL -0 Entity )- SL -0 DTO )- PL] -0 - это интерфейс )- - это потребитель интерфейса То есть, Service Layer обращается к DAL, получает Entity. Presentation обращается к интерфейсам Service Layer, получает DTO. DTO являются моделью, которые рендерятся на веб-странице. Но это общий случаи, реальность может значительно от него отличаться. Рассматриваем ваш случаи. У вас он выглядит вот так: [СУБД] - [DAL -0 Entity )- SL -0 Entity )- PL] То есть PL общается с SL и получает обратно не готовую модель в виде DTO, а получает сущности. Из этого сразу следует несколько проблем: 1) Вы связываетесь с сессией Хибера. 2) Вам приходится разруливать всякие проблемы с Lazy load. Что надо сделать, что бы решить эти проблемы? Вам надо полностью отделить PL от Хибера, полностью. Что бы он вообще не знал, что Хибер есть в проекте. 1) Вы вводите слой DTO объектов. С большой вероятностью, они будут повторять структуру ваших сущностей, но в них не будет зависимостей. То есть вместо сущности Department: Код: java 1. 2. 3. 4. 5. У вас будет вот такой DTO: Код: java 1. 2. 3. 4. Обратите внимание, что у него нет поля employees. Это сделано сознательно, так как цель это DTO - отрендерить только департамент. При таком подходе вы не сможете выстрелить себе в ногу, столкнувшись с Lazy load. 2) Далее, возникает вопрос - ну а как мне получить теперь список сотрудников департамента? Очень легко - надо просто написать fine-grained сервисы, которые будут это делать. То есть вместо: Код: java 1. 2. 3. Сделать Код: java 1. 2. 3. 4. 5. 6. 3) Ок, интерфейсы спроектировали, теперь пишете их реализацию. В реализации надо решить вопрос, как мапить данные из сущностей на данные DTO. Можно руками перегонять, можно воспользоваться какой-нибудь библиотекой, типа commons beanutils. 4) Сервисы готовы, DTO готовы, вводим сессию сервелетов. 5) Далее, надо спроектировать контекст пользователя, в котором будут храниться данные обо всех внесенных им изменениях. За основу можете посмотреть на иходники класса ActionQueue в Хибере. То есть это будет что-то типа (пишу, что сходу в голову пришло): Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 6) Далее пишите контроллеры. Что они будут делать? Два действия - сначала лезут в соответствующий сервис, получают инофрмацию из БД, потом проверяют контекст на наличие изменений, применяют их, потому выдают моедль пользователю. Пример - получения списка сотрудников департамента: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 7) Ну и, наконец, создаете контроллер, который будет сохранять в БД все, что есть в UserContext, когда пользователь желает сохранить изменения. Все. Громоздко? Да. Но зато это правильный подход, который использует все сильные стороны ООП и вообще никак не зависит от всяких Lazy-загрузок и сессий хибера. Вам не надо детачить сессию и потом заново приаттачивать, вам не надо беспокоиться о длинных транзакциях - их тут просто нет, вам не надо беспокоиться о том, когда Хибер вздумает зафлашить что-то, и т.д.. Для тех, кто читает невнимательно или желает потроллить, повторюсь - это псевдокод, он не предназначен для использования. Его цель - только показать идею. Второй важный момент. То, что я написал, это пример того, как делается "по уму". Но, к сожалению, коммерческое программирование это не академическая наука, а бизнес. И бизнес обязывает подстраиваться под него - под бюджет, под временные рамки, под политическую подковерную игру, под заморочки и тараканы определнных людей, и т.д.. Невозможно все всегда делать по уму - бизнес тупо не ползволяет. А поэтому надо всегда сначала формировать в голове правильное решение, а потом думать, несколько окружающая обстановка позволяет его применить. Если позволяет - отлично, применяем. Если не позволяет (сроки горят, менеджер задуплил по жесткому и т.д..), то надо подстраиваться под ситуацию, и, возможно, отказываться от правильного решения в пользу того, которое наиболее подойдет к конкретной ситуации. Я кончил, сотрите с доски ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 14:09:15 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, Спс. за титанический труд. Ты узнал, каково это публично выставлять код :) Весь это метод действительно - академический. Он есть в сети, и также есть критика ОТ применения его в реальных проектах. ЗЫ. Оффтоп в моей теме рядом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 14:23:26 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123Спс. за титанический труд. Ты узнал, каково это публично выставлять код :)Вы о чем? Petro123Весь это метод действительно - академический. Он есть в сети, и также есть критика ОТ применения его в реальных проектах.То, что я здесь показал - это помесь доменной модели с паттерном MVC. Если есть какие-то претензии к доменной модели или MVC - задавайте вопросы. "Есть в сети" - это флейм чистой воды. Поел уже ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 14:37:10 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, - я про то, что сильно жёстко критиковал код ShSerge. off в моей теме рядом. У меня есть ещё один метод, попозже попрошу тебя проанализировать его. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 14:44:47 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123- я про то, что сильно жёстко критиковал код ShSerge.Я не мог критиковать код ShSerge , так как он никакого кода не приводил в рамках того топика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 15:49:33 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, огромное спасибо за ответ и ваш труд Но в моем случаи к сожалению DTO не будет, увы в этом проекте в который я пришел, специально делали так чтоб PL общался напрямую с хибером, чтоб не плодить дто и не тратить время на конвертации, а также главное, чтоб иметь возможность в нужное время обращаться к лази полям и не писать отдельные запросы как вы привели в примере. В прошлом своем проекте, я как раз использовал схему что вы предложили, но тут уже никак. 1) далее: но ваш подход не решает или я посмотрел 1 проблемы, а конкретно добавление в выборку созданных сущностей: "но вот добавлять которых нет, уже не совсем ясно, ведь запросы могли быть по условиям, а не простой селект всех из списка, а если по условии то не факт, что в результат выборки нужно добавить все новые объекты получаемого типа из мапа, может быть только половина подходит. к примеру на первой вкладке добавили двух пользователей с именами Петя, Вася. А на второй делаем запрос "найти всех пользователей чье имя начинается на П" тогда в эту выборку нужно добавить только 1 пользователя из мапа, а не двух. " Причем так как задача у меня стоит написать универсальный визард, то условий я не знаю заранее, имеется ли хорошее решения этой проблемы и если да, то какое???? 2) И еще, вы писали : "Теперь внимание - все HQL/SQL запросы, все критерии - НЕ ИДУТ через кэш первого уровня, они в него не смотрят. Они вытаскивают инормацию сразу из БД и только потом кладут ее в кеш. Поэтому, если вы что-то создали, но не сделали flush(), то нет никакого способа заставить ХИбер вытащить это через HQL запрос. Вообще никак." но проведя эксперимент у меня получилось так: get(A.class, 1); исправил в нем какое-то поле и после сделал так: createQuery("from A").list(); то в результате в списке объектов А будет объект с ид-1 с уже измененным значением поле. То есть хибер заменил объект из выборки на тот что хранится в памяти ну или смержил, внутренностей не знаю. То есть получается что все же не минует кэш первого уровня, ведь измененный но еще не сохраненный в базу объект он подхватил из кэша! Почему в этом случаи это работает???? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:19:28 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
и еще дополнение по второму вопросу: (по update объекты), то есть он кладет его в кэш и мержит с тем, что уже там есть, по правилу простой замены, типа тот что уже есть в кэше круче(новее/правильнее) берем его? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:24:05 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, IMHO п.1 универсальный, значит он ничего не знает о содержании контейнерных вкладок и транзакциях в них. Из этого вытекает, что при нажатии Сохранить на родителе вкладок происходит сброс в БД и переоткрытие всех вкладок. Соответственно, при изменении связанных сущностей на вкладке А, при переходе на вкл. Б нужно либо спросить (Обновить\Не обновлять?) либо останутся старые данные. Это надо уточнить и закрепить в ТЗ у заказчика. Иначе будет слишком сильная кастомизация меньше универсализм. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:31:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, п.2 11900154 - get find - лезет в БД через кэш - любой SQL запрос сначала делает flush, а потом сам запрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:35:56 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
можно ещё доавтоматизировать - в классе Вкладка поставить флаг "Требуется перезапрос модели". Если не читал, а Редактировал, то проставить. При смене вкладки Родитель опросит её. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:39:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyв нужное время обращаться к лази полям да. т.е. в динамике подгрузить их при отдаче в VIEW? или просто чохом все когда достали из ОРМ? (бывает так делают рекурсивно :) ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:42:38 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery 1) далее: но ваш подход не решает или я посмотрел 1 проблемы, а конкретно добавление в выборку созданных сущностей: "но вот добавлять которых нет, уже не совсем ясно, ведь запросы могли быть по условиям, а не простой селект всех из списка, а если по условии то не факт, что в результат выборки нужно добавить все новые объекты получаемого типа из мапа, может быть только половина подходит. к примеру на первой вкладке добавили двух пользователей с именами Петя, Вася. А на второй делаем запрос "найти всех пользователей чье имя начинается на П" тогда в эту выборку нужно добавить только 1 пользователя из мапа, а не двух. " Причем так как задача у меня стоит написать универсальный визард, то условий я не знаю заранее, имеется ли хорошее решения этой проблемы и если да, то какое???? Ну опять таки - через HQL это нерешаемо. Через сервисы - запросто. Делаете что-то типо getByNameStartWith(String startWith). Этот метод выполняет запрос к базе, потом анализирует содержимое контекста, и объединяет обе коллекции. slippery 2) И еще, вы писали : "Теперь внимание - все HQL/SQL запросы, все критерии - НЕ ИДУТ через кэш первого уровня, они в него не смотрят. Они вытаскивают инормацию сразу из БД и только потом кладут ее в кеш. Поэтому, если вы что-то создали, но не сделали flush(), то нет никакого способа заставить ХИбер вытащить это через HQL запрос. Вообще никак." но проведя эксперимент у меня получилось так: get(A.class, 1); исправил в нем какое-то поле и после сделал так: createQuery("from A").list(); то в результате в списке объектов А будет объект с ид-1 с уже измененным значением поле. То есть хибер заменил объект из выборки на тот что хранится в памяти ну или смержил, внутренностей не знаю. То есть получается что все же не минует кэш первого уровня, ведь измененный но еще не сохраненный в базу объект он подхватил из кэша! Почему в этом случаи это работает????Это немного другое. В этом сценарии вы сначала вытащили некий объект в сессию. Потом имзенили его, но не отправили изменения в БД. Потом вы снова вытащили этот же объект из БД. Хибер выполнил реальный запрос, стал класть результаты в сессию, заметил, что в сессии уже есть объект класса A с id = 1, и не стал перезаписывать его состояние. Так что это ожидаемо. Ну и резюме: как я и думал, все проблемы у вас идут из-за неправильных решений при проектировании. Вы должны понимать, что сессия Хибера это абсолютно чужеродный объект в слое презентации. Сушности, прикрепленные к контексту Хибера это тоже чужеродные объекты для презентации, но при аккуратном использовании их можно все-таки сувать в PL. То есть вы сознательно лишили себя необходимого интерфейса в видо DTO для перехода от доменной модели к PL и обратно, засунули в PL сессию Хибера и теперь мучаетесь с ней. Выхода только два - либо идти моим путем и делать все по уму, либо придумывать всякие велосипедные или неестественные решения (например, как я привел выше - лезть в потроха Хибера). Третьего не дано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:48:45 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123- любой SQL запрос сначала делает flush, а потом сам запрос.Неверно. Никакого flush() не происходит. То есть, правильнее - it depends. В случае автора - с отключенным автоматическим flush(), его не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:50:17 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyи еще дополнение по второму вопросу: (по update объекты), то есть он кладет его в кэш и мержит с тем, что уже там есть, по правилу простой замены, типа тот что уже есть в кэше круче(новее/правильнее) берем его?Сессионный "круче" по дефолту. Но это, скорее всего, можно как-то регулировать. Может быть - setCacheMode() поможет, может еще как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:52:21 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomPetro123- любой SQL запрос сначала делает flush, а потом сам запрос.Неверно. Никакого flush() не происходит. То есть, правильнее - it depends. В случае автора - с отключенным автоматическим flush(), его не будет. давай так: - по умолчанию (если не отключал) - верно - если отключил, то я читал что flush он падла и иногда делает :). Ты можешь поручиться что он сам ни разу не сбросит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:53:48 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomТретьего не дано. эх... молодость...категоричность ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:56:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123- get find - лезет в БД через кэш . а можно про это подробнее в каком смысле в БД через кэш? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:56:45 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomslipperyи еще дополнение по второму вопросу: (по update объекты), то есть он кладет его в кэш и мержит с тем, что уже там есть, по правилу простой замены, типа тот что уже есть в кэше круче(новее/правильнее) берем его?Сессионный "круче" по дефолту. Но это, скорее всего, можно как-то регулировать. Может быть - setCacheMode() поможет, может еще как. перед тем как положить "пометить что он круче". Merge "если не в курсе" и более долгий\затратный ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:58:06 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyPetro123- get find - лезет в БД через кэш . а можно про это подробнее в каком смысле в БД через кэш? любой кэш может быть пустой. Есть объект - берём. Т.е. сначала в кэш - буквально. Есть выражение - при запросе - проскакиваем в БД мимо кэша. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 18:59:45 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
PEtro123- по умолчанию (если не отключал) - верноХз, надо тестировать. В случае SQL запроса - уверен на 95%, что это не так. По поводу HQL - просто сильно сомневаюсь. Petro123- если отключил, то я читал что flush он падла и иногда делает :). Ты можешь поручиться что он сам ни разу не сбросит?Я не могу поручаться за чужой код. Откройте исходники и посмотрите. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:01:35 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123svenomТретьего не дано. эх... молодость...категоричность Ждем от вас других вариантов решения. Мои два по сути звучат так: либо дальше мучаться от неправильного решения, принятого ранее, либо же заменить его на правильное. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:02:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
аффтар! У меня к тебе вопрос: - ты вроде хотел решить задачку методом "оттягивая flush() до конца". - отказался? У меня пока такая инфа, что хибер может сбросить сам, несмотря на ручной флаг. Т.е. это не метод для решения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:02:53 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, я тебе назвал вариант, ты про него только - давай код. Это не так скоро. Концепция - отсоединил и присоединил В ДРУГОЙ ТРАНЗАКЦИИ И ХИБЕР-СЕССИИ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:04:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123аффтар! У меня к тебе вопрос: - ты вроде хотел решить задачку методом "оттягивая flush() до конца". - отказался? У меня пока такая инфа, что хибер может сбросить сам, несмотря на ручной флаг. Т.е. это не метод для решения. у меня такой инфы нет, пока остаюсь на этот варианте, если вдруг найдете доказательство сообщите пожалуйста, в моем эксперименте сброса не было, но он не претендует на 100 процентную истину svenom, не могу я поменять архитектуру, придется многое переписать и изменить, а как вы говорили ранее бизнес есть бизнес и такую потерю времени мне не разрешат, так что надо найти наиболее красивое решение с учетом данного момента. Petro123, вы писали: "любой кэш может быть пустой. Есть объект - берём. Т.е. сначала в кэш - буквально. Есть выражение - при запросе - проскакиваем в БД мимо кэша." то есть, если это будет запрос, то он минуте кэш и смотреть в него не будет при методе find так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:08:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123Концепция - отсоединил и присоединил В ДРУГОЙ ТРАНЗАКЦИИ И ХИБЕР-СЕССИИ.Плохая концепция, так как сессия для этого не предназначена. Если приходится отсоединять/присоединять сессию - это очень большой повод задуматься о правильности решения. Ибо сессия должна жить в пределах срока жизни транзакции. Действие "внес какие-то изменения, но в базу не сохранил" - это не транзакция, это просто некое промежуточное действие пользователя. Последние два предложения - ключ к пониманию проблемы автора. Короче, попытка впихнуть невпихуемое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:09:40 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, - странно, что Твой вариант даже никто не рассматривал. Т.е. это и есть самое простое решения и аналог длинных в РСУБД. Я впервую очередь надеюсь на него - Код: plaintext 1. 2. 3. 4. так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:14:03 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomPetro123Концепция - отсоединил и присоединил В ДРУГОЙ ТРАНЗАКЦИИ И ХИБЕР-СЕССИИ.Плохая концепция, так как сессия для этого не предназначена. Если приходится отсоединять/присоединять сессию - это очень большой повод задуматься о правильности решения. Ибо сессия должна жить в пределах срока жизни транзакции. Действие "внес какие-то изменения, но в базу не сохранил" - это не транзакция, это просто некое промежуточное действие пользователя. Последние два предложения - ключ к пониманию проблемы автора. Короче, попытка впихнуть невпихуемое. попытка решить задачу минимальным написанием кода) ведь например кроме того, что вынимать объекты из памяти и фильтровать выборки, надо еще и хранить очередность вставки потом при "последнем" коммите. кстати насчет фильтрации выборок, это разработчикам закладок придется делать самим, руками, что тоже не есть гуд по моим требованием, я конечно понимаю, что условия моей задачи наталкивают на это. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:17:53 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyто есть, если это будет запрос, то он минуте кэш и смотреть в него не будет при методе find так? не так. При автомате. - метод с Query будет 1) хибер сбросит в БД чтобы синхронизировать себя с БД. Он не дурак и видит что юзвер лезет в БД а не к нему. Я бы тоже так сделал. - метод Find \ Get ищет в оперативке и Хибер знает :) = flash() не делает. Логично? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:20:33 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slippery, - странно, что Твой вариант даже никто не рассматривал. Т.е. это и есть самое простое решения и аналог длинных в РСУБД. Я впервую очередь надеюсь на него - Код: plaintext 1. 2. 3. 4. так? да, задумка моя была именно такая и это работает на моем тестовом примере, что я попробовал, когда операция идет с 1 объектом, ну и возникают траблы когда вот надо контролировать связанные объекты, то есть фильтровать выборки объектов которые не связаны в entity отношением с редактируемым главным объектом(объект от которого начинаем плясать когда открываем визард) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:20:38 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123slipperyто есть, если это будет запрос, то он минуте кэш и смотреть в него не будет при методе find так? не так. При автомате. - метод с Query будет 1) хибер сбросит в БД чтобы синхронизировать себя с БД. Он не дурак и видит что юзвер лезет в БД а не к нему. Я бы тоже так сделал. - метод Find \ Get ищет в оперативке и Хибер знает :) = flash() не делает. Логично? к примеру запрос: List users = session.find("from UserInfo as u where u.fullName = ?", "John Doe", Hibernate.STRING ); какая логика работы в данном случаи? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:22:48 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
в смысле, что он будет искать в кеше, будет ли он искать в кеше и как он будет это делать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:24:29 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, если работает, то замечательно. Я выше написал по вкладкам. Если вкладка дала знать о необходимости перезапроса ВСЕМ (invalidate() в WinAPI :) ) это работает? Ты бы хотел запросы к Модели в оперативе-кэше? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:24:46 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Что-то я читал, читал тему и нипойму в чем проблема. стартуем транзакцию. делаем че хотим, при этом флушим в бд после добавлений-удалений, так как транзакция НЕ ЗАКОМИЧЕНА дургие конекты-юзеры не увидят наших изменений. Если юзер передумает, то откатываем транзакцию и все. или у вас сессии короче чем ваша длиииная бизнес транзакция? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:25:12 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123, надо подумать :) В БД не сбросил, но запросы хотишь :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:26:29 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyв смысле, что он будет искать в кеше, будет ли он искать в кеше и как он будет это делать?Ну так это обычный HQL запрос. Работает так же, как я описал выше: 1. Идет запрос к БД, формируется список полученных объектов 2. Объекты мерджатся в сессию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:27:45 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsov, да, в веб сессия хибера и транзакция только в рамках запроса HTTP-реквеста. У нас :)) несколько реквестов на бизнес транз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:28:18 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey KuznetsovЧто-то я читал, читал тему и нипойму в чем проблема. стартуем транзакцию. делаем че хотим, при этом флушим в бд после добавлений-удалений, так как транзакция НЕ ЗАКОМИЧЕНА дургие конекты-юзеры не увидят наших изменений. Если юзер передумает, то откатываем транзакцию и все. или у вас сессии короче чем ваша длиииная бизнес транзакция?Это классическая длинная транзакция со своими плюсами (простоа реализации) и минусами (абсолютная немасштабируеомсть). Подходит это автору или нет - вопрос к нему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:29:21 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, я не понял - есть класс А изменённый в хибере, но не сброшенный в БД. Что произойдёт? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:29:42 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
хибер сравнит метку версии и ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:31:08 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123svenom, я не понял - есть класс А изменённый в хибере, но не сброшенный в БД. Что произойдёт?Что произойдет при каком действии? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:31:40 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, если знаешь - ответь. Я не знаю спросил. В RTFM? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:34:32 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomslipperyв смысле, что он будет искать в кеше, будет ли он искать в кеше и как он будет это делать?Ну так это обычный HQL запрос. Работает так же, как я описал выше: 1. Идет запрос к БД, формируется список полученных объектов 2. Объекты мерджатся в сессию. блин, ну вот почему он не реализовали при мержде объектов, что если в сессии объект с таким id со статусом "удалить", то чтоб он не попадал в выборку, по моему же логично было бы, разе нет? и сделать 2 варианта запросов, чтоб в 1 попадал, а во втором нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:34:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123svenom, я не понял - есть класс А изменённый в хибере, но не сброшенный в БД. Что произойдёт?Что произойдет при каком действии? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:37:50 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenomAlexey KuznetsovЧто-то я читал, читал тему и нипойму в чем проблема. стартуем транзакцию. делаем че хотим, при этом флушим в бд после добавлений-удалений, так как транзакция НЕ ЗАКОМИЧЕНА дургие конекты-юзеры не увидят наших изменений. Если юзер передумает, то откатываем транзакцию и все. или у вас сессии короче чем ваша длиииная бизнес транзакция?Это классическая длинная транзакция со своими плюсами (простоа реализации) и минусами (абсолютная немасштабируеомсть). Подходит это автору или нет - вопрос к нему. Классическая длинная транзакция не вариант как мне кажется, потому, что параллельно в веб приложении таких транзакций может быть открыто 1000 и более и открыты они могут быть на часы, насколько я понимаю это неимоверная нагрузка на СУБД так же и на память самого сервера. Если я ошибаюсь и у кого-то есть какие-нибудь сведения или информация по этому поводу с огромным удовольствием выслушаю. Но я всегда слышал, и где-то читал, что делать так в веб приложении в котором могут параллельно работать тысячи или десятки тысяч пользователей, это значит "убить" проект. Хотелось бы мне ошибаться..... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:38:39 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperysvenomпропущено... Это классическая длинная транзакция со своими плюсами (простоа реализации) и минусами (абсолютная немасштабируеомсть). Подходит это автору или нет - вопрос к нему. Классическая длинная транзакция не вариант как мне кажется, потому, что параллельно в веб приложении таких транзакций может быть открыто 1000 и более и открыты они могут быть на часы, насколько я понимаю это неимоверная нагрузка на СУБД так же и на память самого сервера. Если я ошибаюсь и у кого-то есть какие-нибудь сведения или информация по этому поводу с огромным удовольствием выслушаю. Но я всегда слышал, и где-то читал, что делать так в веб приложении в котором могут параллельно работать тысячи или десятки тысяч пользователей, это значит "убить" проект. Хотелось бы мне ошибаться.....Все верно. На каждую такую транзакцию нужен отдельный коннекшн со всеми вытекающими. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:40:30 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, если хибер не умеет, то очень просто - он не СУБД и умеет в себе копаться только ограниченно . Т.е. ломай DDL командами сколько угодно, но не перезапрашивай . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:41:57 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperysvenomпропущено... Ну так это обычный HQL запрос. Работает так же, как я описал выше: 1. Идет запрос к БД, формируется список полученных объектов 2. Объекты мерджатся в сессию. блин, ну вот почему он не реализовали при мержде объектов, что если в сессии объект с таким id со статусом "удалить", то чтоб он не попадал в выборку, по моему же логично было бы, разе нет? и сделать 2 варианта запросов, чтоб в 1 попадал, а во втором нет. Ну опять таки - все корректно отработает, как вы ожидаете, если вы сделаете flush() перед исполнением запроса. Вы flush() делать не хотите, Хибер тут ни при чем. Вы у него попросили вернуть список определнных объектов - он вам их и вернул. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:44:15 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, вопрос чуть не по теме, а чем session.createQuery от session.find() глобально отличается? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:46:30 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperysession.createQuery от session.find() глобально отличается?Метода find либо нет, либо он диприкейтед ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:48:55 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, Хибер то ни при чём я согласен. Веб-ТЗ при чём. И программисты, которые ленивые стали. IDE им подавай и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:50:51 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123, в общем, автор! Тайм-аут и объясни заказчику. Либо долго писать чтобы хибер был импотентом прослойкой до БД. Либо менять ТЗ уменьшив УНИВЕРСАЛЬНОСТЬ как зло для IT. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 19:53:28 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Petro123Petro123, в общем, автор! Тайм-аут и объясни заказчику. Либо долго писать чтобы хибер был импотентом прослойкой до БД. Либо менять ТЗ уменьшив УНИВЕРСАЛЬНОСТЬ как зло для IT. по глобальной концепции уменьшать универсальность нельзя, поэтому видимо "долго или нудно писать руками" вообщем-то я уже смирился с этой мыслю) единственное не хотелось бы написать криво, так как подобное раньше мне делать не приходилось, потому и спрашивал какие есть подходы, варианты, паттерны, фрэймворки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 20:00:23 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, ok универсальность проще не на тонком клиенте и не на веб. Но есть минусы! В параллельной теме тоже ищу сабж. Удачи! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 20:23:40 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyДобрый день, есть задача: Открываю сессию с hibernate, начинаю транзакцию, создаю 2 объекта и делаю им save. slippery, как вы привели ТЗ в соседнем топике, так там все нормально, грамотно и просто. Про HQL это заказчик так сказал или вы сами? View не должен работать с СУБД. Между ними еще есть слой DAO и Service и не забываем про модель. Т.е. ваш пользователь в своих вкладках работает с моделью, при необходимости подгружая данные из СУБД. Вы реализуете все операции типа delete/insert в памяти (можно в сервисах, если сделать цикл жизни не singleton, а как у сессии), а далее при запросе от пользователя просто сохраняете все изменения в БД. Вкладки работают только с сервисами и моделями, что и позволяет нам утвреждать, что они ничего друг от друге не знают. Собственно, я похожую задачу решал, только в desktop приложении, что для вас совершенно не важно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2012, 20:33:27 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Теперь понял. Тогда остается еще такое решение: делаете маркерное поле и выборки делаете с учетом маркерного поля, что бы другие коннекты не тащили "логически незакомиченные" данные. Что бы упростить написание запросов, таблицы можно вьюхами обернуть, которые автоматом отфильтруют данные. Я один раз похожее решение использовал: флажок "IsDeleted" который приходилось постоянно иметь ввиду при написании запросов, муторно, но другого выхода думаю нету. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 08:18:12 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey KuznetsovТеперь понял. Тогда остается еще такое решение: делаете маркерное поле и выборки делаете с учетом маркерного поля, что бы другие коннекты не тащили "логически незакомиченные" данные. Что бы упростить написание запросов, таблицы можно вьюхами обернуть, которые автоматом отфильтруют данные. Я один раз похожее решение использовал: флажок "IsDeleted" который приходилось постоянно иметь ввиду при написании запросов, муторно, но другого выхода думаю нету.Ваше решение не подходит по нескольким причинам: 1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 09:54:21 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, +1 В субд (не орм) работает уровень изоляции READ_COMMITED для этого. Это можно сделать руками, но лучше бы это УЖЕ было. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 10:00:37 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. флаг IsDeleted я привел для своего случая, у вас видимо будет что-то более сложное, скорее всего поле с ID "логической" транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:24:15 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsovsvenom1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. флаг IsDeleted я привел для своего случая, у вас видимо будет что-то более сложное, скорее всего поле с ID "логической" транзакции. да, конечно так можно решить. Это метод "READ_COMMITED - вручную". Но блин, это нужно проводить через весь функционал Хибера. Это нужно проводить через всю Модель. Т.е. то что контролирует БД, нужно протягивать по всем уровням. Когда тут налево и направо все кричат о преимуществах инжекции, декларативных и Великом помощнике Спринге. Не факт, что данный метод проще чем перед транзакцией кидать объекты в сессию HTTP и потом обратно мержить их. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:50:06 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
возможно проще iBatis взять, если у хибера такие заморочки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:51:08 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsovsvenom1) Как быть с новыми записями? Т.е. которые созданы пользователем, но еще не закомичены? 2) Флаг isDeleted будет действовать и на всех остальных пользователей. Т.е. один юзер что-то удалил, но еще не сохранил, при этом все остальные юзеры уже увидят эти изменения. Это неправильно. флаг IsDeleted я привел для своего случая, у вас видимо будет что-то более сложное, скорее всего поле с ID "логической" транзакции.Ну это все равно велосипед, так как у автора есть апп. сервер и именно он должен хранить состояние сесии пользователя, а не СУБД. Ваш подход подошел бы в двухзвенке или каких-то особых случаях трехзвенки (например - кластер с сохранением состояния в БД). Какие минусы: 1) Лишние операции с СУБД, лишний сетевой траффик 2) Проблемы с поддержанием целостности информации. Например, пользователь удаляет какую-то строку, потом пытается сохранить изменения, но в этот момент апп. сервер падает (вырубили электричество, а ИБП замкнуло ). В итоге, после рестарта сервака в СУБД имеется запись об удалении, которая уже не связана ни с какой сессией и вообще ХЗ что с ней делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:54:35 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Alexey Kuznetsovфлаг IsDeleted я привел для своего случая, помню по своим проектам, и проектам 1С, что требование в ТЗ "сущность не удаляется, а как-бы удаляется" порождает такие проблемы для разработчика и архитектуры... Если там конечно, достаточно связей и логики между ними. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:56:05 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, ну да, только пока непонятно, как делать запросы к не сброшенным в БД данным или до flush(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 12:58:54 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
заказчику: Всегда лучше сперва попробовать использовать в приложении традиционные ACID-свойства (длинные с вкладками). Но если вы готовы пожертвовать некоторой частью согласованности БД и целостности данных ради производительности, стоит рассмотреть стратегию высокой производительности (короткие транзакции без вкладок) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 13:04:12 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
вообщем поразмыслив я пришел к выводу, что модель(не держим сессию, во всех закладках только читаем данные, все изменения храним в структуре памяти и передаем через сессию или еще как и накатываем в конце. а выборки фильтруем в ручную) которую предложил svenom. тоже имеет минусы: 1. это необходимо все писать руками) 2. необходимо также вести очередь изменений, так как порядок важен при итоговом сохранении 3. и главное: необходимо фильтровать выборки руками причем тут тоже проблемы: а) фильтрация на удаленные элементы, запросили 20 на страницу, выяснили что 2 из них удалены, удалили их из результата, в итоге отдаем на страницу 18. Пользователю не понятно почему так, почему не 20....а подгрузить еще 2 недостающих это и лишний запрос к бд, и нарушение логики, ведь они попадут и на следующую страницу(запрос следующих 20) при пэйджинге. Как быть в этом случаи???? б) добавление элементов которые в памяти в выборки по условию тоже сложный процесс, разработчики вкладок должны будут бегать по коллекциям и сверять подходят ли добавленные элементы под их условия или нет. что совсем не прозрачно и накладывает дополнительные усилия на разработку закладок, чего заказчик хотел избежать. Вообщем совсем жизнь не сладка......к тому же вопрос из пункта 3.а, остается открытым, как быть в такой ситуации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 20:20:34 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
LeonidvView не должен работать с СУБД. Между ними еще есть слой DAO и Service и не забываем про модель. Т.е. ваш пользователь в своих вкладках работает с моделью, при необходимости подгружая данные из СУБД. Вы реализуете все операции типа delete/insert в памяти (можно в сервисах, если сделать цикл жизни не singleton, а как у сессии), а далее при запросе от пользователя просто сохраняете все изменения в БД. Вкладки работают только с сервисами и моделями, что и позволяет нам утвреждать, что они ничего друг от друге не знают. Вы наверно не совсем верно поняли, да по задумке вкладки работают только с сервисами, но они должны получать/знать изменения которые были сделаны на предыдущих вкладках. Посмотрите мое предыдущее сообщение(на 1 выше этого) и увидите какие возникают проблемы и вопросы в данном подходе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 20:27:49 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery3. и главное: необходимо фильтровать выборки руками причем тут тоже проблемы: а) фильтрация на удаленные элементы, запросили 20 на страницу, выяснили что 2 из них удалены, удалили их из результата, в итоге отдаем на страницу 18. Пользователю не понятно почему так, почему не 20....а подгрузить еще 2 недостающих это и лишний запрос к бд, и нарушение логики, ведь они попадут и на следующую страницу(запрос следующих 20) при пэйджинге. Как быть в этом случаи???? уж запрос на выборку с параметрами limit и offset для разработчика вкладок должен быть прозрачным наверняка и то, что мы в результат не включили 2 удаленных элемента его не касается, это должно быть не им сделано, а "мной" то есть в обертки на сервис или еще как. Есть идеи по этому поводу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 20:34:39 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slippery, Ну тогда реализуйте эту логику на уровне БД, как Alexey Kuznetsov предлагал выше. Придумываете некую таблицу (или таблицы - одну для изменений, другую - для удалений, третью - для созданных записей), в которой будут храниться изменения, например CREATE TABLE ... ( id, session_id, table_name, ... ) Тут ключевое поле - session_id - идентификатор сессии. Дальше фикачите кучу всяких вьюшек, которые будут отображать данные с учетом изменений пользователя. Далее навешиваете на эти вьюхи триггеры, которые будут не только сохранять изменения в релаьные таблицы, но и будут чистить вспомогательные. Далее создаете какую-либо джобу, которая будет периодически подчищать "мусор" во вспомогательных таблицах после нештатных ситуаций (напр., вырубили электричество, как я говорил выше). Далее навешиваете на сессию пользователя листенер, что бы при закрытии сессии, чистились записи, относящиеся к этой сессии, во вспомогательных таблицах. Минусы - лишний траффик в БД до коммита пользователя, много дополнительного кода на уровне СУБД. Плюсы - автоматом решаются проблемы с пейджингом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:01:02 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Мне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:16:48 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪМне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию.В вашем решении абсолютно не важно будет использован Хибер или нет. Если да - просто делаем flush(), а потом откатываем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:29:55 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪМне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию. хм.....интересный вариант, мне только от хибера отказываться нельзя, таково требование не рушимое, но сама идея интересна, к примеру на хибере 1) есть "главная сессия" она открывается при первом запросе 2) все удаления, добавления проводятся через "главную сессию" 3) при выборках "главная" сессия клонируется(если такое возможно, я не знаю) , открывается транзакция в клонированной сесии, сбрасывается(флаш) выполняется выборка, транзакция откатывается и клонированная сессия закрывается 4) в итоге при завершаещем коммите либо сбрасываем(флэш) "главную" сессию либо закрываем ее Кто что думает? возможен ли такой вариант? если возможен в чем его минусы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:30:33 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
или даже не нужно клонировать сессию, а просто делать флаш перед выборкой и откатывать в конце? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:31:52 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyЙуный джавистЪМне тут пришла мысль, как можно решить задачу с использованием только коротких транзакций. Решение не использует Hibernate. 1)Все изменения таблицы храним в Http сессии. Изменения - это три списка: -- список id удаленных строк -- список новых строк -- список измененных строк 2)Пока пользователь редактирует данные(создает, изменяет или удаляет строки), http запросы обрабатываются по такой схеме: -- открываем транзакцию -- скидываем изменения в БД(создаем, удаляем и изменяем строки, в соответствии со списками пункта 1) -- дальше делаем запросы для получения нужных данных (пейджинг и прочее). Так как изменения скинуты в БД, пейджинг и все остальное будет работать правильно. --в конце обработки http запроса откатываем транзакцию 3)Если пользователь решает отменить все изменения, то удаляем списки из пункта 1. 4)Если пользователь решает применить изменения, то скидываем изменения в базу и комитим транзакцию. хм.....интересный вариант, мне только от хибера отказываться нельзя, таково требование не рушимое, но сама идея интересна, к примеру на хибере 1) есть "главная сессия" она открывается при первом запросе 2) все удаления, добавления проводятся через "главную сессию" 3) при выборках "главная" сессия клонируется(если такое возможно, я не знаю) , открывается транзакция в клонированной сесии, сбрасывается(флаш) выполняется выборка, транзакция откатывается и клонированная сессия закрывается 4) в итоге при завершаещем коммите либо сбрасываем(флэш) "главную" сессию либо закрываем ее Кто что думает? возможен ли такой вариант? если возможен в чем его минусы?Не прокетит. Еще раз повторяю - сессия Хибера не прденазначена для решения этой задачи, ее нельзя сюда пихать в принципе. Йуный джавистЪ предлагает немного модифицированное мое решение: создаем все ту же структуру в Http сессии. На каждой операции чтения происходит следующее - все изменения сначала сбрасываются в базу (не важно как - хотите через JDBC, хотите через Хибер - пофиг), после этого происходит считывание необходимой информации, а потом откат транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:34:59 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, а можете объяснить почему не прокатит??? ведь сессия хибера и так в себе содержит подобные структуры что вы предлагаете сделать руками(то есть хранит что надо удалить что обновить и т.д.) почему если клонировать сессию то не получится? хотя возможно ее нельзя клонировать, этого я не знаю ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:46:24 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
svenom, В вашем решении абсолютно не важно будет использован Хибер или нет. Согласен, если использовать session per request, как вы и советовали. Если держать hibernate сессию между запросами, как пытался slippery, то гибернейт тут никак не приспособить. Йуный джавистЪ предлагает немного модифицированное мое решение Да, так и есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 21:50:50 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪsvenom, В вашем решении абсолютно не важно будет использован Хибер или нет. Согласен, если использовать session per request, как вы и советовали. Если держать hibernate сессию между запросами, как пытался slippery, то гибернейт тут никак не приспособить. Йуный джавистЪ предлагает немного модифицированное мое решение Да, так и есть. кстати как я понимаю в таком решении нельзя использовать декларативное управление транзакциями от спринга @Transactional над методами сервисов, ибо как я понял спринг принудительно закрывает(коммитит) транзакцию открытую или открывает и закрывает новую. И еще а можно как-нибудь отключить в рантайме этот механизм, сделать так чтоб обращения к сервисам из определенных мест проходило в не спринговского перехватчика ну или что-то еще в этом духе, ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:01:26 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
просто проект в который я уже пришел разрабатывался по методу: не полностью продуманная архитектура в самом начале, а быстро быстро накидывать функционал для показов, а дальше уже по мере появления решать задачи, и так я пришел в готовый проект в котором сессия сейчас открывается по запросу, декларативное управления транзакциями через спринг. и вот мне выдана такая задача, так что тут еще момент с интеграцией решения в проект существует. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:03:32 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Мысль клонировать сессию хибернейта интересная, но я в целом не советую вам это делать. Экономия усилий не такая большая, а перспектива развлечься с хибернейтом вполне реальная. Кроме того, подумайте, разберется ли с этим ваш последователь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:08:09 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperysvenom, а можете объяснить почему не прокатит??? ведь сессия хибера и так в себе содержит подобные структуры что вы предлагаете сделать руками(то есть хранит что надо удалить что обновить и т.д.) почему если клонировать сессию то не получится? хотя возможно ее нельзя клонировать, этого я не знаю1. Сессия Хибера не содержит реализации метода clone(). 2) Ее нельзя сериализовать-десериализовать, так как в ней присутствуют несериализуемые зависимые объекты (транзакция, коннекшн и т.д..) А когда вы делаете flush() вы изменяете состояние сессии и нельзя потом заставить сделать ее этот же flush() еще раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:13:04 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪМысль клонировать сессию хибернейта интересная, но я в целом не советую вам это делать. Экономия усилий не такая большая, а перспектива развлечься с хибернейтом вполне реальная. Кроме того, подумайте, разберется ли с этим ваш последователь. спасибо за ответы, думал что-то наподобие этого использовать: public <T> T clone(T obj){ T theClone = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); ObjectInputStream ois = new ObjectInputStream( new ByteArrayInputStream(baos.toByteArray()) ); theClone = (T)ois.readObject(); но и правда возникает вопрос с объектами внутри сессии которые имеют лайзи поля. Просто хотелось бы по минимому писать код, чем его будет меньше тем и легче разобраться?) а про предыдущие вопросы насчет отключения в рантайме декларативного управления спрингом транзакций, ну или изменения чтоб он не во всех случаях автокомит делал, что нибудь знаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:14:22 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperyкстати как я понимаю в таком решении нельзя использовать декларативное управление транзакциями от спринга @Transactional над методами сервисов, ибо как я понял спринг принудительно закрывает(коммитит) транзакцию открытую или открывает и закрывает новую. И еще а можно как-нибудь отключить в рантайме этот механизм, сделать так чтоб обращения к сервисам из определенных мест проходило в не спринговского перехватчика ну или что-то еще в этом духе,Да, спринг пытается закомитить транзакцию в конце, но вы можете помешать ему сделать это. Например - выбросить исключение или выставить флаг "rollback only". То есть будут нормальные сервисы, а будут сервисы-обертки, которые открывают транзакцию, к которой потом присоединятся нормальные сервисы, а в конце метода инициирует ее откат. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:15:26 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
Йуный джавистЪ, ничего не понял. Если без хибера, то достаточно на сервер дать команду старт транзакции. и всё что ты будешь делать с данными увидишь только ты. Что и требует заказчик. ОК? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:51:20 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
я читал инфу, что спринг самовольно закрывает не только транзакцию, но сессию хибера. Потом на LAZY объекты идёт исключение. Надо тестить. А откуда спринг в задаче? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 22:53:15 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
упс. понял откуда спринг ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 23:01:20 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
slipperysvenom, а можете объяснить почему не прокатит??? ведь сессия хибера и так в себе содержит подобные структуры что вы предлагаете сделать руками(то есть хранит что надо удалить что обновить и т.д.) почему если клонировать сессию то не получится? хотя возможно ее нельзя клонировать, этого я не знаю я тебе советовал деаттачить объекты в сессии. Так по крайней мере делают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2012, 23:05:58 |
|
||
|
Hibernate, работа с Session
|
|||
|---|---|---|---|
|
#18+
а для запросов к изменённым данным это вы оригинально придумали ;) - скинуть в БД для запросов, запросить всё что надо и откатить СУБД обманули :) ------ вот можно ещё подумать как применить Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2012, 00:16:36 |
|
||
|
|

start [/forum/topic.php?all=1&fid=59&tid=2132841]: |
0ms |
get settings: |
10ms |
get forum list: |
22ms |
check forum access: |
6ms |
check topic access: |
6ms |
track hit: |
49ms |
get topic data: |
15ms |
get forum data: |
4ms |
get page messages: |
200ms |
get tp. blocked users: |
2ms |
| others: | 348ms |
| total: | 662ms |

| 0 / 0 |
