I want to create a public Object getById(Class class, long id)
function. I tried creating query like:" from :nameEntity where id=:id " but I'm facing problems when setting parameter for 'nameEntity'. Hibernate doesn't recognize it as a parameter.
Don't build a query, use the load()
or get()
methods from the Session
. They are actually heavily overloaded, allowing to pass the class either as Class
or String
, the persistent object identifier and, if required, a lock option (for pessimistic locking):
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)
What are the differences between get()
and load()
? This is explained in the Reference Documentation:
The load()
methods of Session
provide a way of retrieving a
persistent instance if you know its
identifier. load()
takes a class
object and loads the state into a
newly instantiated instance of that
class in a persistent state.
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) );
Alternatively, you can load state into
a given instance:
Cat cat = new DomesticCat();
// load pk's state into cat
sess.load( cat, new Long(pkId) );
Set kittens = cat.getKittens();
Be aware that load()
will throw an
unrecoverable exception if there is no
matching database row. If the class is
mapped with a proxy, load()
just
returns an uninitialized proxy and
does not actually hit the database
until you invoke a method of the
proxy. This is useful if you wish to
create an association to an object
without actually loading it from the
database. It also allows multiple
instances to be loaded as a batch if
batch-size is defined for the class
mapping.
If you are not certain that a matching
row exists, you should use the get()
method which hits the database
immediately and returns null
if
there is no matching row.
Cat cat = (Cat) sess.get(Cat.class, id);
if (cat==null) {
cat = new Cat();
sess.save(cat, id);
}
return cat;
You can even load an object using an
SQL SELECT ... FOR UPDATE, using a
LockMode. See the API documentation
for more information.
Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);
Any associated instances or contained
collections will not be selected FOR
UPDATE, unless you decide to specify
lock or all as a cascade style for the
association.
It is possible to re-load an object
and all its collections at any time,
using the refresh()
method. This is
useful when database triggers are used
to initialize some of the properties
of the object.
sess.save(cat);
sess.flush(); //force the SQL INSERT
sess.refresh(cat); //re-read the state (after the trigger executes)
How much does Hibernate load from the
database and how many SQL SELECTs will
it use? This depends on the fetching
strategy. This is explained in Section
20.1, “Fetching strategies”.
How to choose between them?
Choosing between get()
and
load()
is easy: If you’re certain the
persistent object exists, and
nonexistence would be considered
exceptional, load()
is a good option.
If you aren’t certain there is a
persistent instance with the given
identifier, use get()
and test the
return value to see if it’s null
.
See also
Related question