Reputation: 394
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 with 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 :
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.
Upvotes: 2
Views: 2039
Reputation: 691775
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
}
Upvotes: 4