Hibernate proxy loading with only the primary key
We have the following relation:
A car is owned by a person. A person can own many cars.Here is the mapping for the car :
<hibernate-mapping package="fr.recouv.scribe.core.bo">
<class name="Car" table="car">
<id name="id" column="id_car" unsaved-value="0">
<generator class="sequence">
<param name="sequence">car_id_car_seq</param>
</generator>
</id>
<many-to-one name="person" update="false" column="id_person" class="Person" />
<property
</class>
I have a webservice wi开发者_如何转开发th this signature :
public void insert(Car car, int idPersonOwner)
I want to insert a car for a specific person given his id. Right now my code looks like this :
Car car = new Car();
Person owner = personDao.get(idPersonOwner);
car.setPerson(owner);
carDao.save(car);
And the hibernate implementation for personDao.get(idPersonOwner) looks like
public Person get(in idPerson){
return session.get(Person.class, id);
}
Drawback of this method :
- the all Person object is loading even if i need from a SQL view just his id
- the operation could generate MORE that 2 queries if the mapping of person evolve (like lazy loading set to false etc.)
My actual workaround : It is to directly map the foreign key to an integer
<property column="id_person" name="idPerson" />
This solution is not object oriented and less beautiful. And if tomorrow i need to retrieve the owner of a car I have to remap the person object like previous and update=false
Is it possible to load ONLY a proxy of Person given his id that will result with a query to verify if this person exists with his primary key and optionally load the others fields in a lazy mode if they are called.
I have tried session.load but this is not the solution. The object is never null(no query testing his existence) or no exception are thrown until you access an other field to load for real the object from the database.
Yes, that's precisely what session.load
(EntityManager.getReference
if using JPA) is for. It loads a proxy to the object, assuming the entity exists.
Of course, you might have an exception if at commit time, a foreign key constraint breaks because the person doesn't actually exist. But you might also have it with Session.get
if some other transaction deletes the person before committing.
If you really want to check that the person exists, execute a dedicated query returning just a boolean (or a count), and the use Session.load
when you know that the person exists:
Number count =
session.createQuery("select count(p.id) from Person p where p.id = :theId")
.setLong("theId", theId)
.uniqueResult();
if (count.intValue() > 0) {
Person p = session.load(Person.class, theId);
}
else {
// throw exception
}
精彩评论