2010-01-07 2 views
0

Я пишу приложение GWT, используя Hibernate на стороне сервера. Сейчас я совершенно смущен правильным способом переноса моих объектов на клиентскую сторону приложения GWT в наименьшем количестве кода. Я использую Gilead, чтобы избежать удвоения количества классов в моей модели домена [1].Hibernate, GWT и Gilead: сеансы, транзакции и кэши

Прежде всего, мой вопрос заключается в том, как я должен открывать сессии и транзакции. Первоначально я сделал это на каждом RPC сервер вызова:

// begin rpc call 
getCurrentSession 
beginTransaction 
// ...do stuff 
commit 
// session is automatically closed 
// end rpc call 

Поскольку это открывает и закрывает сессию для каждого вызова RPC, делает это также создает новое соединение с сервером базы данных каждый раз?

Во всяком случае, как только я начинаю с помощью лениво загружены коллекциями, я получаю следующее исключение, используя этот шаблон:

org.hibernate.HibernateException: collection is not associated with any session 
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)` 

Мне кажется, что сессия была закрыта до Gilead получает возможность упорядочивания коллекции объект, и это вызывает исключение.

Так что я попытался исправить это явно открывая заседание сам, что предотвращает его от закрывается автоматически после каждой транзакции, например так:

openSession 
// begin rpc call 
beginTransaction 
// ...do stuff 
commit 
// end rpc call 

// next rpc call 
beginTransaction 
// ...etc 

Однако, когда я это делаю, я видя все виды фанкового поведения, связанные с кешем объектов сеанса. Во-первых, createQuery(). ExecuteUpdate(), похоже, не отменяет кеш сеанса, хотя я читал на разных сайтах, которые он должен. Когда я попытался исправить это, пытаясь сделать недействительным кеш сеанса, вызвав различные перестановки session.flush(), session.clear() и т. Д., Следующая ошибка была «ClassCastException: null» при сериализации глубоко внутри Gilead или Beanlib ,

С другой стороны, когда я пытаюсь что-то вроде этого:

clients get an object from the server 
client modifies object 
client sends object back 
server calls session.saveOrUpdate() 

Я получаю сообщение об ошибке, как «другой объект с тем же идентификатором уже в кэше сеанса».

Каков правильный способ установить такие вещи? Как мне охватить мои сеансы и как я должен обращаться с кешем? Я не могу себе представить, что я единственный, кто пытается это сделать, и у меня проблемы, но хорошие гиды, похоже, трудно найти.

[1] http://code.google.com/webtoolkit/articles/using_gwt_with_hibernate.html

+0

относительно последней проблемы, с которой вы столкнулись: «другой объект с тем же идентификатором уже находится в кеше сеанса», вы должны использовать слияние, как при использовании saveOrUpdate, он предполагает, что нет объекта с тем же идентификатор в кеше сеанса и что в БД может быть такой (следовательно, илиUpdate). все еще есть объект snet для клиента в сеансе, который необходимо использовать для слияния. См. Также: http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/ – Ittai

ответ

0

Take a look a this answer и ниже комментарии.

Вопрос не в том, что у вас есть - это обобщение вашего - то есть как объединить JPA (Hibernate) с удалением (то есть сериализации объектов и отправки их для чтения по проводам). Это непростая и тривиальная проблема, хотя она является обычной. Проверьте мои предложения там и сделайте комментарий здесь, если вы что-то не понимаете.

0

Я не использую Gilead, так что это может быть частью проблемы, но я использую сеансы ThreadLocal. В каждом вызове rpc я обертываю логику в методе, который всегда закрывает сеанс ThreadLocal перед окончательным возвратом. Сессия открывается для этого потока при первом запросе.

Однако перед закрытием сеанса вам необходимо полностью инициализировать все прокси.Скорее всего, GWT пытается сериализовать ваш POJO после закрытия сессии и когда он попадает в прокси-сервер или ленивую коллекцию, он непреднамеренно пытается инициализировать его. Лично я либо беру удар по копированию POJO для разделения объектов, либо я уверен, что точно знаю, какие поля будут сериализованы и «коснуться» их раньше времени (например, путем вызова размера() в коллекции. это сложно, если у вас есть глубоко вложенные объекты.

Было бы неплохо, если бы был крючок GWT, позволяющий выполнять код после сериализации, но до завершения цикла rpc. Возможно, что есть, и я просто не знаю об этом

 Смежные вопросы

  • Нет связанных вопросов^_^