有一些这样的类:
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {
@Id
@GeneratedValue
private int personId;
其子类为:
@Entity
@Table(name="employee")
@PrimaryKeyJoinColumn(name="employee_id")
public class Employee extends Person {
[Something else fields]
需要提及的是,还有其他一些从Person扩展的对象(例如Student)具有自己的Fk字段(例如student_id)到Person实体。
以下HQL的生成的查询:
select count(e)
from Employee e
是:
select count(e.id)
from employee e
inner join person p
on e.employee_id = p.id
而正确生成的查询必须是:
select count(e.employee_id)
from employee e
inner join person p
on e.employee_id = p.id
因此,引发了
invalid identifier
异常。哪里错了,我该怎么做才能解决这个问题?
更新
这些实体的表是:
人:
id and others files
------------------------------------
员工表是:
employee_id[fk to person table] others fields
----------------------------------------------------
最佳答案
尽管Hibernate允许这种继承,但是由于结果/行为对开发人员的控制较少,因此通常避免使用。
相反,根据我以前的经验和恕我直言,我建议您遵循以下做法,该做法将从JPA 2.0开始,通过使用@JoinColumn为您提供更多控制权,以实现预期的结果:
@Entity
@Table(name="person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="person_id")
private Long personId;
}
@Entity
@Table(name="employee")
public class Employee{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="employee_id")
private Long employeeId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn (name="person_id")
private Person person;
}
更新1
如果更优选使用@PrimaryKeyJoinColumn,则原始代码中需要纠正一件事(至少需要为PK分配名称以提供更多控制权):
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {
@Id
@GeneratedValue
@Column(name="person_id")
private int personId;
}
@Entity
@Table(name="employee")
@PrimaryKeyJoinColumn(name="person_id")
public class Employee extends Person {
@GeneratedValue
@Column(name="employee_id")
private int employeeId;
}
这是因为
@PrimaryKeyJoinColumn
应该让当前的辅助表知道需要引用主表的哪个主键。您可以参考JPA 2.0规范的以下部分:
11.1.40 PrimaryKeyJoinColumn注释
PrimaryKeyJoinColumn
批注指定一个主键列,该列用作连接到另一个表的外键。PrimaryKeyJoinColumn
批注用于连接主表JOINED
映射策略中的实体子类到主对象的定义其超类表;在
SecondaryTable
批注中使用将辅助表连接到主表;它可以用于
OneToOne
映射,其中引用实体的主键为用作参考实体的外键[108]。