在数据库上更新视图时,Hibernate搜索不会更新视图的索引

时间:2018-08-16 06:04:37

标签: elasticsearch lucene hibernate-search elasticsearch-5 nhibernate-search

在我的项目中,我们使用Lucene和Hibernate Search / ORM 5.9.2。如果在数据库中更新了表,则工作得很好,相同的更改也反映在ES索引上。但是数据库视图的索引不会更新。值存在于数据库下,但不存在于索引下。

我需要通过Hibernate搜索实现哪些相应的策略/逻辑?

有关引用我的实现的任何代码都可以在implemented code under the Java files下找到。

此外,假设我有2个类A和B,而C是A + B的视图。我将C存储在弹性索引中。一旦在数据库下更新了A和B,C是否有可能被更新?当我使用Hibernate search + lucene注释时。

当通过Hibernate实体在数据库下更新表时,Hibernate搜索将在索引下对其进行更新。但是,由于视图是在SQL Server端更新的,因此不会发生这种现象。是否可以通过Lucene /休眠搜索来实现?

1 个答案:

答案 0 :(得分:1)

休眠搜索在实体级别运行。因此,它看不到您直接在数据库中所做的更改。

要让Hibernate Search管理索引,您需要依赖实体。

实际上,它是别无选择的,因为这是它的设计宗旨。

如果对实体进行了更改,则可以实现自己的侦听器层来处理C或使C成为实体,并实现触发器(如果数据库可以做到的话,则放弃对它的更新查询)。

如果更改是直接对数据库进行的,那么使用Hibernate Search会很不幸。或者,每次更改数据库以触发索引时,您都必须在应用程序中触发某些服务。

顺便说一句,您是否需要数据库级别的此视图?因为如果仅在Elasticsearch级别上需要它,则可以使C成为对A和B具有@OneToOne的适当实体,并使用@IndexedEmbedded@ContainedIn对A和B的内容进行索引另一边。这样可以解决您的原生Hibernate Search问题。

我想我会尝试:

 @Entity
 @Indexed
 public class C {
     @Id
     @GeneratedValue
     private Long id;

     @OneToOne(mappedBy = "a")
     // you might need a prefix if some fields are common between a and b
     @IndexedEmbedded
     private A a;

     @OneToOne(mappedBy = "b")
     // you might need a prefix if some fields are common between a and b
     @IndexedEmbedded
     private B b;
 }

然后进入A(与B相同):

@Entity
@Indexed
public class A {
    // the existing content of your A class

    @OneToOne(cascade = CascadeType.ALL)
    @ContainedIn
    private C c;

    public setC(C c) {
        if ( c != null ) {
            c.setA( this );
        }
        this.c = c;
    }
}

然后,在首次创建A和B时,还需要创建一个C并将其注入到A和B中:

C c = new C();
a.setC( c );
b.setC( c );

em.persist( a );
em.persist( c );

完成此操作后,无论何时更新A或B,都应使用@ContainedIn批注重新索引C。