バックグラウンド
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に移動しても、リスナーは呼び出されません。
1 つの修正
@EntityListeners
注釈をPartTimeEmployeeまで移動すると、彼が呼び出されます。うーん。
別の修正
Personにリスナーを登録したままにすることができ、 Employeeのアノテーションを完全に省略した場合、リスナーは意図したとおりに呼び出されます。しかしもちろん、私は望んでいない単一のテーブル戦略を手に入れました。同様に、ストラテジーの値を から に変更すると、リスナーが呼び出されます。もちろん唯一の問題は、データベース スキーマが思い通りにならないことです。@Inheritance
InheritanceType.TABLE_PER_CLASS
InheritanceType.SINGLE_TABLE
したがって、ここでの問題の核心は、従業員@Inheritance
クラスの注釈 (より具体的には、クラスごとに 1 つのテーブルへの戦略の変更) であり、階層内のエンティティ リスナーに関するすべてを EclipseLink に忘れさせます。
それは私が期待していたものではありません。私が理解できないのは何ですか?