沐鸣注册网站java有趣的内容播客

我将代码基从EclipseLink作为JPA提供者切换到Hibernate,并发现在Hibernate中您不能在事件监听器类中使用继承。JPA规范没有详细讨论这个主题,因此JPA提供者必须处理彼此不同的问题。沐鸣注册网站
我将实体侦听器从实体中分离出来,即使可以在实体类中直接添加注释如@PostPersist的方法。实体侦听器本身并不复杂,但也只是稍微复杂一些:我为所有实体侦听器创建了一个通用基类,并为每个实体创建了专门化子类。
公共类EntityListenerBase {
@PostPersist
public void postpersistent (T object) {
SomeEventBus.sendEvent (createPostPersistEvent(对象));
}
受保护的抽象事件createPostPersistEvent(T对象);
}
公共类ThingEntityListener扩展了EntityListenerBase {
@Override
受保护事件createPostPersistEvent(Thing Thing) {
返回新ThingAdded(的事);
}
}
将实体侦听器添加到实体非常简单:只需将@ entitylistener注释添加到实体并将其指向侦听器。沐鸣注册平台
@ entity
@EntityListeners (ThingEntityListener.class)
公共类ThingEntity实现了Thing {
…
}
EclipseLink在使用这样的事件侦听器时完全没有问题。问题是在我将JPA提供者切换到Hibernate之后开始的:在某个时候,我意识到应用程序显然不再生成任何响应持久性事件的事件。就好像实体监听器根本不存在一样!
在对Hibernate如何管理其事件监听器进行了较长时间的调试之后,我发现我以前的事件监听器方法不再可行,原因有二。
第一个原因是Hibernate坚持在实体监听器类中直接声明带注释的事件方法。从超类继承的方法不会扫描事件注释!这与实体类本身的方法被注释时的行为不同;在这种情况下,使用@MappedSuperclass注释的超类也将用于定位事件侦听器方法。但是,对于实体侦听器类则不是这样。沐鸣登陆地址
在将postpersistent方法向下移动到子类时,我偶然发现了第二个原因:对于每个事件注释,Hibernate只允许在实体监听器类中使用一个方法进行注释。现在,因为原始postpersistent方法有一个泛型参数,而子类有一个固定的类型参数,所以编译器创建了该方法的两个版本,一个是Object作为参数类型,另一个是我想要的实际类型Thing。其中一个方法被标记为synthetic,但是两个方法都获得注释,Hibernate不喜欢这样。不是。一个。一些。
因此,解决方案很简单,即使这意味着在所有实体侦听器上有一些代码重复:只需从事件侦听器中删除类型层次结构。
公共类ThingEntityListener {
@PostPersist
public void postPersist(Thing Thing) {
SomeEventBus。sendEvent(新ThingAdded(事情));
}
}
有人可能会说这实际上更好;更少的类层次结构和所有相关的侦听器方法都在类中,增加了可见性并降低了复杂性。