How to convert an ORM to its subclass using Hibernate ?
- by Gaaston
Hi everybody,
For example, I have two classes : Person and Employee (Employee is a subclass of Person).
Person : has a lastname and a firstname.
Employee : has also a salary.
On the client-side, I have a single HTML form where i can fill the person informations (like lastname and firstname). I also have a "switch" between "Person" and "Employee", and if the switch is on Employee I can fill the salary field.
On the server-side, Servlets receive informations from the client and use the Hibernate framework to create/update data to/from the database. The mapping i'm using is a single table for persons and employee, with a discriminator.
I don't know how to convert a Person in an Employee.
I firstly tried to :
load the Person p from the database
create an empty Employee e object
copy values from p into e
set the salary value
save e into the database
But i couldn't, as I also copy the ID, and so Hibernate told me they where two instanciated ORM with the same id.
And I can't cast a Person into an Employee directly, as Person is Employee's superclass.
There seems to be a dirty way : delete the person, and create an employee with the same informations, but I don't really like it..
So I'd appreciate any help on that :)
Some precisions :
The person class :
public class Person {
protected int id;
protected String firstName;
protected String lastName;
// usual getters and setters
}
The employee class :
public class Employee extends Person {
// string for now
protected String salary;
// usual getters and setters
}
And in the servlet :
// type is the "switch"
if(request.getParameter("type").equals("Employee")) {
Employee employee = daoPerson.getEmployee(Integer.valueOf(request.getParameter("ID")));
modifyPerson(employee, request);
employee.setSalary(request.getParameter("salary"));
daoPerson.save(employee );
}
else {
Person person = daoPerson.getPerson(Integer.valueOf(request.getParameter("ID")));
modifyPerson(employee, request);
daoPerson.save(person);
}
And finally, the loading (in the dao) :
public Contact getPerson(int ID){
Session session = HibernateSessionFactory.getSession();
Person p = (Person) session.load(Person.class, new Integer(ID));
return p;
}
public Contact getEmployee(int ID){
Session session = HibernateSessionFactory.getSession();
Employee = (Employee) session.load(Employee.class, new Integer(ID));
return p;
}
With this, i'm getting a ClassCastException when trying to load a Person using getEmployee.
XML Hibernate mapping :
<class name="domain.Person" table="PERSON" discriminator-value="P">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<discriminator column="type" type="character"/>
<property name="firstName" type="java.lang.String">
<column name="FIRSTNAME" />
</property>
<property name="lastName" type="java.lang.String">
<column name="LASTNAME" />
</property>
<subclass name="domain.Employee" discriminator-value="E">
<property name="salary" column="SALARY" type="java.lang.String" />
</subclass>
</class>
Is it clear enough ? :-/