有一些这样的类:

@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]。

10-06 08:53