【发布时间】:2013-03-20 08:44:22
【问题描述】:
背景
我正在使用 EclipseLink(版本 2.3.2.v20111125-r10461,JPA 2.0 规范的实现提供者)。
考虑一下这个名为Person的@MappedSuperclass:
@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,他就会被调用。嗯。
另一个修复
我们可以让监听器在 Person 上注册,并且监听器将按预期调用,如果我们完全省略 Employee@Inheritance 注释/强>。但是当然,我得到了一个我不想拥有的单桌策略。同样,我们可以更明确一点,将策略值从InheritanceType.TABLE_PER_CLASS 更改为InheritanceType.SINGLE_TABLE,然后将调用侦听器。当然,唯一的问题是我的数据库架构看起来不像我想要的那样。
所以,这里问题的核心是 Employee 类上的@Inheritance 注释(更具体地说;将策略更改为每个类一个表),这使得 EclipseLink 忘记了所有关于实体侦听器的内容层次结构。
这完全不是我所期望的。有什么不明白的?
【问题讨论】:
标签: jakarta-ee jpa-2.0 mappedsuperclass entitylisteners table-per-class