例如,我有两个类:Person和Employee(Employee是Person的子类)。 人:有一个姓氏和一个名字。 员工:还有薪水。
在客户端,我有一个HTML表单,我可以填写人员信息(如姓氏和名字)。我在“人员”和“员工”之间也有一个“切换”,如果交换机在员工上,我可以填写工资字段。
在服务器端,Servlet从客户端接收信息,并使用Hibernate框架在数据库中创建/更新数据。我正在使用的映射是针对个人和员工的单个表,带有鉴别器。
我不知道如何将Person
转换为Employee
,方法是修改type
,DiscriminatorColumn
用作public class Person {
protected int id;
protected String firstName;
protected String lastName;
// usual getters and setters
}
。
我首先尝试:
但我不能,因为我也复制了ID,所以Hibernate告诉我他们两个实例化的ORM具有相同的ID。
我不能直接将Person转换为Employee,因为Person是Employee的超类。
似乎有一种肮脏的方式:删除这个人,并创建一个具有相同信息的员工,但我真的不喜欢它..
所以我很感激任何帮助:)
一些准确性:
人员班:
public class Employee extends Person {
// string for now
protected String salary;
// usual getters and setters
}
员工类:
// 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);
}
在servlet中:
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;
}
最后,加载(在dao中):
<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>
有了这个,我在尝试使用getEmployee加载Person时遇到ClassCastException。
XML Hibernate映射:
{{1}}
足够清楚了吗? : - /
答案 0 :(得分:4)
几年前,当我做了一次评论时,我发现了一个可以解决问题的糟糕的黑客攻击。
当我理解你的时候 - 你需要将一个人转变为一个雇员然后回来。 他们使用了一个鉴别器列,我们称之为“disc”,并假设你使用一个带有两个值PERSON和EMPLOYEE的字符串鉴别器。然后你需要一个额外的列,将鉴别器列映射到你的Person类。我们称之为“hackType”。
@Column(columnName=”disc”)
private String hackType;
现在你已经加入了hackType和Object的类型。首先,您需要确保所有员工的hackType为PERSON,所有员工为EMPLOYEE。 - 但是如果你想将一个Person“转移”给一个Employee,你只需要加载Person(按ID),将其字段hackType设置为EMPLOYEE,保存它,清除缓存,并将其重新加载(通过ID)作为雇员。
但这是一个非常糟糕的黑客,我已经看到它用于nHibernate,但我认为它也适用于(Java)Hibernate。 - 无论如何我强烈建议不要这样做,但知道这个黑客很有意思。
至少我认为问题在于您的域模型是错误的:员工不应该是Person的子类。因为这意味着Employee将始终是Employee和Person(如果它是作为一个人创建的)将永远不会成为一个员工。我强烈建议在Person和Employee之间建立1:1的关系。 Person是主要对象,Employee是Person的可选扩展。 (在这种情况下,您需要将Employee重命名为像EmploymentFacts这样的东西,以明确这只是一个人的员工部分。)
答案 1 :(得分:0)
我认为没有好的出路。您可以在此人上触发更新查询以将其类型修改为“E”并更改薪水,如果仍需要,则可以使用getEmployee()
获取该更新。