单独指定 JPA 实体侦听器,独立于其关联实体
Posted
技术标签:
【中文标题】单独指定 JPA 实体侦听器,独立于其关联实体【英文标题】:Specifying JPA entity listeners separately being independent of its associated entity 【发布时间】:2015-12-15 15:00:48 【问题描述】:实体侦听器通常放置在相应的实体类上,例如,
@Entity
@EntityListeners(EntityListener.class)
public class Entity implements Serializable
//...
应用程序可以使用一个或多个类库在不同的项目/模块之间共享通用功能。除了 EE 模块之外,类库基本上还要求实体作为依赖项存在于编译时类路径中,即实体存在于企业应用程序中的类库和 EE 模块这两个地方。因此,给定示例中的类 EntityListener
需要存在于类库的编译时类路径中(它不能只添加到 EE 模块中)。
如果实体侦听器不与各个实体紧密耦合并单独指定,则无需将此依赖项(侦听器)添加到类库中,即实体侦听器将仅存在于 EE 项目中其中 EJB 完全可以使用 @Inject
进行注入。
是否有可能将此注释@EntityListeners(EntityListener.class)
与其关联实体分开,以便可以在单独的位置单独声明?不需要将此注释与其各自的实体紧密耦合。
使用具有 EclipseLink 2.6.0 (JPA 2.1) 的 GlassFish 4.1。
这是必需的,因为有一个 problem 使用 CDI 特定工件 @Inject
将 EJB 注入到此类实体侦听器中在类库中可用。如果侦听器仅存在于 EE 项目(模块)中(而不存在于类库中),则可以通过使用 @Inject
将 EJB 注入到侦听器中。
【问题讨论】:
【参考方案1】:将注释@EntityListeners
从实体中取出的一种方法是同时使用XML 和注释方法。混合和匹配 XML 描述符和元数据注释是完全有效和记录的。
为了覆盖该注释,必须在名为 orm.xml
[1] 的文件中注册实体侦听器,如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd">
<entity class="com.example.entity.Entity">
<entity-listeners>
<entity-listener class="com.example.entity.listeners.EntityListener"/>
</entity-listeners>
</entity>
<!--Other listeners-->
</entity-mappings>
相应的监听器类可以保持不变,注释如下。
public class EntityListener
@PostPersist
@PostUpdate
@PostRemove
public void onChange(Entity entity)
// Do something with the entity.
这些回调可能会因功能要求而异。
如有必要,还可以将回调定义为 XML 元素,避免在侦听器类中添加回调注释,例如,
<entity class="com.example.entity.Entity">
<entity-listeners>
<entity-listener class="com.example.entity.listeners.EntityListener">
<post-persist method-name="onChange"/>
<post-update method-name="onChange"/>
<post-remove method-name="onChange"/>
</entity-listener>
</entity-listeners>
</entity>
现在不需要监听器类中的这三个注解,即@PostPersist
、@PostUpdate
和@PostRemove
,因为它们已在 XML 描述符中注册。
[1] 像 NetBeans 这样的 IDE 似乎没有生成 orm.xml
文件的向导支持。在 NetBeans 项目中,需要在 src/conf
(或任何其他自定义配置位置)下手动创建一个 XML 文件,以便应用程序构建者可以在构建/部署应用程序时将该文件放在 META-INF/orm.xml
下。
【讨论】:
【参考方案2】:是的,您可以使用 xml 定义 default entity listener。
【讨论】:
接收当前持久化单元中所有实体的所有事件的默认监听器要做什么? 听说过if statement? :) 还是地图(实体实例类型 -> 您的自定义侦听器实现)?毕竟,这或多或少是 JPA 提供者注册和查找侦听器的方式;他们提供了直接在实体上定义它的快捷方式,这只是一种方便。 我接受了我自己的答案,因为它实际上对我有用。以上是关于单独指定 JPA 实体侦听器,独立于其关联实体的主要内容,如果未能解决你的问题,请参考以下文章
在 JPA 中,我如何找到具有属性值的所有类型和具有属性值的 ManyTomany 相关实体?