elasticsearch,Java,Hibernate,Circular Dependency,elasticsearch" /> elasticsearch,Java,Hibernate,Circular Dependency,elasticsearch" />

Java 如何将侦听hibernate事件的模块与实体本身解耦?

Java 如何将侦听hibernate事件的模块与实体本身解耦?,java,hibernate,circular-dependency,elasticsearch,Java,Hibernate,Circular Dependency,elasticsearch,我有一个由spring jpa hibernate驱动的分层web应用程序,现在我正在尝试集成elasticsearch(搜索引擎) 我想做的是捕获所有postInsert/postUpdate事件,并将这些实体发送到elasticsearch,以便它将它们重新编制索引 我面临的问题是,我的“dal实体”项目将对“搜索索引器”具有运行时依赖性,“搜索索引器”将对“dal实体”具有编译依赖性,因为它需要为不同的实体执行不同的操作 我曾考虑将“搜索索引器”作为DAL的一部分(因为可以说它对数据进行操

我有一个由spring jpa hibernate驱动的分层web应用程序,现在我正在尝试集成elasticsearch(搜索引擎)

我想做的是捕获所有postInsert/postUpdate事件,并将这些实体发送到elasticsearch,以便它将它们重新编制索引

我面临的问题是,我的“dal实体”项目将对“搜索索引器”具有运行时依赖性,“搜索索引器”将对“dal实体”具有编译依赖性,因为它需要为不同的实体执行不同的操作

我曾考虑将“搜索索引器”作为DAL的一部分(因为可以说它对数据进行操作),但它仍然应该作为DAO部分的一部分

我认为我的问题可以重新表述为:如何在hibernate事件监听器中拥有不能单独封装在entities项目中的逻辑(因为这不是它的责任)

更新
dal实体项目依赖于索引器的原因是我需要在spring配置文件中配置侦听器,该文件负责jpa上下文(显然位于dal实体中)。

依赖项不是编译时范围,而是运行时范围(因为在运行时hibernate上下文将需要该侦听器)。

答案是接口

您不必直接(在任何方向)依赖于各种类,而是可以依赖于展现所需功能的接口。通过这种方式,您不直接依赖于类,而是依赖于接口,并且您可以拥有“dal实体”所需的接口,例如,这些接口与dal实体位于同一个包中,索引器只是实现该接口

这并没有完全消除依赖性,但它确实让您的耦合不那么紧密,并使您的应用程序更加灵活


如果您仍然担心事情的耦合过于紧密,或者您真的不希望这两部分之间存在循环依赖,那么我建议您重新考虑您的应用程序设计。在这里再问一个问题,详细介绍一些代码以及如何更好地构造代码,可能会得到一些关于如何改进设计的好建议。

Hibernate支持PostUpdateEventListener和PostInsertEventListener

这是一个可能适合你的例子

主要概念是能够在实体发生更改时进行定位,并在更改后进行操作,如图所示

public class ElasticSearchListener implements PostUpdateEventListener {

@Override
public void onPostUpdate(PostUpdateEvent event) {
    if (event.getEntity() instanceof ElasticSearchEntity ) {
        callSearchIndexerService(event.getEntity());
        Or 
        InjectedClass.act(event.getEntity());
        Or 
        callWebService(InjectedClassUtility.modifyData(event.getEntity()));

      ........
}
}
编辑

您可以考虑使用Spring将要隔离的项目注入到项目中(保持逻辑)。p> 另一个选项可能是调用不依赖于代码的外部web服务。


将原始项目对象或由实用程序修改的对象传递给它,以适应elasticsearch。

您认为这也适用于简单POJO吗?这是这里的问题,因为dal实体已经只依赖于索引器的接口,但索引器依赖于具体的模型POJO。我曾考虑在POJO上也使用接口,但我不确定这是否是一种方式。我很想知道域POJO如何(或为什么)依赖于索引器。索引器依赖它们是有道理的,但反过来就不行了。您可以发布一个域类(POJO)的示例吗?另外,对于您提出的问题,是的,如果您需要删除依赖项,即使对于非常简单的类,也可以使用接口。看看可运行的接口,毕竟…只有一个方法!我已经添加了解释。如果您认为spring配置文件的实际代码示例更有用,请这样说,我将发布它(只是认为它没有那么有用),您应该能够让spring向索引器提供相同的上下文,因为它必须向JPA提供上下文。使用Spring将依赖关系(上下文)注入到需要它的地方,而不是跨层共享它的类本身,这是一种更好的设计。让类共享是“难闻的”,特别是如果你已经在使用令人惊叹的令人敬畏的DI能力,那就是Spring。谢谢,我知道这些听众,我现在正在使用他们。问题更多的是关于cdeszaq是如何看待它的,即如何设计实体侦听器索引器之间的逻辑耦合。@Ittai,感谢您的评论,更改了我的答案,希望能有所帮助。