Я хочу создать публичную Object getById(Class class, long id)
функцию.Я пытался создать запрос вроде: «from: nameEntity где id =: id», но у меня возникают проблемы при установке параметра для «nameEntity».Hibernate не распознает его как параметр.
Не создавайте запрос, используйте методы load()
или get()
из Session
.Они на самом деле сильно перегружены, что позволяет передавать классу либо Class
, либо String
, постоянный идентификатор объекта и, при необходимости, параметр блокировки (для пессимистической блокировки):
get(Class clazz, Serializable id)
load(Class theClass, Serializable id)
get(Class clazz, Serializable id, LockOptions lockOptions)
load(Class theClass, Serializable id, LockOptions lockOptions)
get(String entityName, Serializable id)
load(String entityName, Serializable id)
get(String entityName, Serializable id, LockOptions lockOptions)
load(String entityName, Serializable id, LockOptions lockOptions)
Что такоеразличия между get()
и load()
?Это объясняется в справочной документации:
Методы load()
для Session
предоставляют способ получения постоянного экземпляра, если вы знаете его идентификатор.load()
берет объект класса и загружает состояние во вновь созданный экземпляр этого класса в постоянном состоянии.
Cat fritz = (Cat) sess.load(Cat.class, generatedId);
// you need to wrap primitive identifiers
long id = 1234;
DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );
В качестве альтернативы, вы можете загрузить состояние в данный экземпляр:
Cat cat = new DomesticCat();
// load pk's state into cat
sess.load( cat, new Long(pkId) );
Set kittens = cat.getKittens();
Имейте в виду, что load()
сгенерирует неисправимое исключение, если нет соответствующей строки базы данных.Если класс сопоставлен с прокси, load()
просто возвращает неинициализированный прокси и фактически не обращается к базе данных, пока вы не вызовете метод прокси.Это полезно, если вы хотите создать ассоциацию с объектом без фактической загрузки его из базы данных.Он также позволяет загружать несколько экземпляров в виде пакета, если для сопоставления классов определен размер пакета.
Если вы не уверены, что соответствующая строка существует, вам следует использовать метод get()
, который попадает вбаза данных немедленно и возвращает null
, если нет подходящей строки.
Cat cat = (Cat) sess.get(Cat.class, id);
if (cat==null) {
cat = new Cat();
sess.save(cat, id);
}
return cat;
Вы даже можете загрузить объект, используя SQL SELECT ... FOR UPDATE, используя LockMode.Для получения дополнительной информации см. Документацию API.
Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);
Любые связанные экземпляры или содержащиеся коллекции не будут выбраны ДЛЯ ОБНОВЛЕНИЯ, если вы не решите указать блокировку или все в качестве каскадного стиля для ассоциации.
Можно повторно загрузить объект и все его коллекции в любое время, используя метод refresh()
.Это полезно, когда триггеры базы данных используются для инициализации некоторых свойств объекта.
sess.save(cat);
sess.flush(); //force the SQL INSERT
sess.refresh(cat); //re-read the state (after the trigger executes)
Сколько загружает Hibernate из базы данных и сколько SQL SELECT будет использовать?Это зависит от стратегии извлечения.Это объясняется в Разделе 20.1, «Стратегии извлечения» .
Как выбирать между ними?
Выбор между get()
и load()
легко: если вы уверены, что постоянный объект существует, и небытие будет считаться исключительным, load()
- хороший вариант.Если вы не уверены, что существует постоянный экземпляр с данным идентификатором, используйте get()
и проверьте возвращаемое значение, чтобы увидеть, является ли оно null
.
См. Также
Смежный вопрос