背景
我正在使用 EclipseLink(版本 2.3.2.v20111125-r10461,JPA 2.0 规范的实现提供程序)。
考虑一下这个@MappedSuperclass
,称为Person:
@MappedSuperclass
@EntityListeners({Listener.class})
public abstract class Person implements Serializable
{
@Id @GeneratedValue
private Long id;
}
他是抽象的,并附有一个听众(Listener )。这是监听器的实现:
public class Listener
{
@PrePersist
public void sayHi(Person person) {
System.out.println("Hi!");
}
}
然后我们有一个扩展Person的Employee类:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Employee extends Person
{
private int salary;
}
Employee仍然是抽象的,并不意味着被实例化。但是, Employee 被认为可能是关系的一部分,因此被注释掉了@Entity
。层次结构继续使用名为PartTimeEmployee的非抽象实体:
@Entity
public class PartTimeEmployee extends Employee
{
private int hoursWorked;
}
PartTimeEmployee旨在被实例化。让我们尝试一下,看看会发生什么!除了一个小细节外,一切似乎都很好。@MappedSuperclass
在Person上注册的实体监听器不会被调用。如果我们将@EntityListeners
注释从Person向上移动到Employee ,甚至不会调用侦听器。
一个修复
将@EntityListeners
注释一直移动到PartTimeEmployee,他将被调用。唔。
另一个修复
如果我们完全省略Employee上的注释,我们可以保持在Person上注册的侦听器,并且侦听器将按预期调用。但是当然,我得到了一个我不想拥有的单桌策略。同样,我们可以更明确一点,将策略值从to更改为,然后将调用侦听器。当然,唯一的问题是我的数据库模式看起来不像我想要的那样。@Inheritance
InheritanceType.TABLE_PER_CLASS
InheritanceType.SINGLE_TABLE
因此,这里问题的核心是Employee@Inheritance
类上的注释(更具体地说;将策略更改为每个类一个表),这使得 EclipseLink 忘记了层次结构中的所有实体侦听器。
这根本不是我所期望的。我不明白的是什么?