2

背景

我正在使用 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更改为,然后将调用侦听器。当然,唯一的问题是我的数据库模式看起来不像我想要的那样。@InheritanceInheritanceType.TABLE_PER_CLASSInheritanceType.SINGLE_TABLE

因此,这里问题的核心是Employee@Inheritance类上的注释(更具体地说;将策略更改为每个类一个表),这使得 EclipseLink 忘记了层次结构中的所有实体侦听器。

这根本不是我所期望的。我不明白的是什么?

4

1 回答 1

1

我想您可能已经发现了一个 EclipseLink 错误,它们在继承注释中很常见。

我建议升级到最新版本的 EclipseLink,你的版本已经超过一年了。如果这不起作用,那么您将不得不用您的侦听器注释您的派生类。

如果你感觉特别喜欢冒险,你可以实现一个 SessionCustomizer,它会在启动时为类添加监听器。

于 2013-03-31T05:07:58.423 回答