2009-07-16 7 views
2

Я столкнулся с ситуацией, когда объект Hibernate, возвращенный из запроса, ненадежный.Ненадежные объекты спящего режима

Рассмотрим следующий код:

MyClass myClass = myDAO.get(id); 

myClass.getId(); //This works 
myClass.getName(); //This returns null sometimes, and works sometimes 

Вот мой Получ:

@SuppressWarnings("unchecked") 
public T get(ID id) 
{ 
    Session s = getSession(); 
    T entity = (T) s.load(getPersistentClass(), id); 
    s.disconnect(); 
    return entity; 
} 

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

ответ

3

Это может быть и не быть причиной, но вы, вероятно, не должны использовать Session.load(), вы должны использовать Session.get().

load() возвращает постоянный экземпляр, который в настоящее время загружен спящим режимом, и, возможно, это частично заполнено в зависимости от того, что произошло раньше.

get() более прочный. Попробуй это.

+0

load() используется по соображениям производительности (согласно рекомендации команды Hibernate). Я дам get() выстрел, но я все равно ожидал бы, что спящий режим будет получать участника, когда его попросят ... – Jesse

+1

У меня была схожая, если не такая же проблема с использованием нагрузки, я изменил на get(), и все снова хорошо () – jottos

+0

Я отмечаю это как ответ. Я изменил с load(), чтобы получить() некоторое время назад, и с тех пор не имел проблемы. – Jesse

1

Проблема «load» будет загружать прокси-объект объекта и фактически не попадать в базу данных. Однако, если объект уже загружен (и заполнен), то есть в кеше уровня 1, он предоставит этот экземпляр.

Когда вы используете нагрузку, она фактически на самом деле попадает в базу данных, когда это абсолютно необходимо, т. Е. Когда вы запрашиваете одно из полей объекта.

Получить с другой стороны на самом деле попадет в базу данных.

Для ваших целей я бы рекомендовал, чтобы вы использовали нагрузку или убедитесь, что объект заселен, прежде чем передавать его обратно. Прежде чем передать его, назовите одного из получателей. Тогда вы можете гарантировать, что он заселен.

Полезным упражнением было бы включить ведение журнала SQL (org.hibernate.SQL = DEBUG), отладить его и посмотреть, какие команды SQL выполняются.

Вы также можете подумать о том, чтобы настроить постоянный объект, который вы загружаете, не лениться. Таким образом, независимо от того, используете ли вы нагрузку или получаете, каждый раз вы будете получать полностью заполненный объект.

+0

Я бы не стал привлекать внимание к отображению гибернации, как вы предполагали. Нежелательная загрузка по умолчанию может привести к большим результатам производительности при загрузке коллекций сопоставленного класса или запросов для представлений, которые не должны отображать все поля сопоставленного класса. Вот почему ленивая загрузка по умолчанию - в Hibernate 3.x –

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