Хорошие идеи для отладки ошибок Hibernate Session / Transaction? - PullRequest
2 голосов
/ 28 октября 2011

Я уже некоторое время пользуюсь Hibernate и привык к большинству распространенных сообщений об ошибках. Большинство указывает мне прямо на проблему, но у меня были проблемы с этим:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

Я понимаю ошибку (у сеанса есть два разных объекта с одинаковым идентификатором), но я не знаю, как найти хороший способ отладки моего кода, чтобы найти источник проблемы. Обычно я смотрю на код, который я сейчас изменяю, и ищу места, где я загружаю один объект и вручную создаю другой, надеясь, что смогу найти простую ошибку в моей логике. Однако в настоящее время я работаю с кодовым набором, который я не написал, с которым я не знаком, и который не имеет документации. Единственное решение, которое я могу придумать, - это построчно просматривать код в надежде найти ошибку. Знаете ли вы о лучшем способе отладки этой ошибки?

Кроме того, точная ошибка, которую я получаю, связана с вызовом saveOrUpdate(), что заставляет меня задаться вопросом, вызывает ли он save(), когда должен вызываться update(). Есть ли способ отыскать объекты, которые есть в Hibernate в текущем сеансе, для целей отладки?

Ответы [ 2 ]

4 голосов
/ 29 октября 2011

saveOrUpdate вызывает update, если у отсоединенного объекта уже есть идентификатор. update затем пытается присоединить данный отдельный объект к сеансу. Поскольку вы можете иметь только один экземпляр данной сущности в сеансе, если вы уже загрузили сущность (используя load, get или запрос) в сеансе во время вызова saveOrUpdate, вы Я получу это исключение.

saveOrUpdate, как правило, должно быть одним из первых действий после открытия сеанса. Если вам необходимо загрузить объект перед его обновлением, вы должны использовать merge. Я обычно предпочитаю использовать merge во всех случаях, потому что он менее подвержен ошибкам.

Вы можете иметь представление о том, что происходит в сеансе, используя session.getStatistics().getEntityKeys().

1 голос
/ 30 октября 2011

Вы также можете установить точку останова в функции Session.Flush и проверить, какие объекты хранятся в персистере. Здесь вы можете найти некоторую информацию о том, как отслеживать события открытия и закрытия сессии - вам, вероятно, нужно тщательно изучить свойство PersistenceContext объекта SessionImpl и событие OnFlush.

Для отладки с исходным кодом вам не нужно перекомпилировать все исходники NHibernate - вы можете связать файлы pdb с исходным файлом zip (см. http://lowleveldesign.wordpress.com/2011/10/02/debugging-nhibernate-prepare-symbol-files/).

...