外部实体更改后索引不更新 [英] index not updating after external entity changes

查看:175
本文介绍了外部实体更改后索引不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个项目,用JPA 2.1保存数据,并使用hibernate search 4.5.0.final搜索实体。

I'm currently working on a project to persist data with JPA 2.1 and to search entities using hibernate search 4.5.0.final.

映射类和索引之后,搜索工作正常。

After mapping classes and indexing, the searching works fine.

然而,当我将classB的值 description 从someStr更改为anotherStr时。数据库已相应更新,但是当我使用Luke检查索引时,索引中的classA.classB.description未更新,并且数据无法通过关键字anotherStr进行搜索,但可以通过关键字someStr进行搜索。

However, when I changed the value description of classB from "someStr" to "anotherStr". The database was updated accordingly, but when I checked the index using Luke, classA.classB.description in the index wasn't updated, and the data cannot be searchable by keyword "anotherStr", but can be searchable by keyword "someStr".

在重新索引整个数据库后,它最终更新。

After I reindex the whole database, it's updated finally.

根据Hibernate搜索网站,

According to Hibernate search website,


简短的回答是索引是自动的:Hibernate Search将透明地索引通过Hibernate ORM持久化,更新或删除的每个实体。它的任务是保持索引和数据库同步,让你忘记这个问题。

The short answer is that indexing is automatic: Hibernate Search will transparently index every entity persisted, updated or removed through Hibernate ORM. Its mission is to keep the index and your database in sync, allowing you to forget about this problem.

但它不能在我的工作案件。我不确定我是否错过了一些细节,或者我需要自己处理这类问题。

But it's not working in my case. I'm not sure if I missed some details or I need to handle it myself for this kind of issues.

我还尝试在classB上添加@Indexed注释通过这一个,但它仍然没有解决我的问题。

I also tried to add annotation @Indexed on classB as suggested by this one, but it's still not solving my problem.

据我所知,解决方案是定期重新索引数据库。但重新索引会禁用搜索功能,在大多数情况下这不是一个选项。

As far as I know, the solution would be to reindex the database periodically. But reindexing would disable the search functionality and that's not an option in most of the cases.

有人能提出一些建议吗?谢谢。

Could anyone give some suggestions? Thanks.

我有一个类,它使用@IndexedEmbedded批注嵌入了其他一些类。这是我的类映射的简化版本。

I have a class which embedded some other classes by using @IndexedEmbedded annotation. Here is a simplified version of my class mapping.

Class A
@Entity(name = "classA")
@Indexed
public class classA extends Model {
    private int id;
    private String name;
    private ClassB place;
    ...
    some constructors
    ...
    @Id
    @GeneratedValue
    @DocumentId
    public int getId() {
        return id;
    }

    @Column(name = "name")
    @Field(analyze = Analyze.NO, store = Store.YES)    // only used for sorting
    public String getName() {
        return name;
    }

    @IndexedEmbedded
    @ManyToOne
    @JoinColumn(name = "place_id")
    public ClassB getPlace() {
        return place;
    }
    ...
}


Class B
@Entity(name = "classB")
public class classB extends Model {
    private int id;
    private String description;
    ...
    some constructors
    ...
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    @Fields({
        @Field,
        @Field(name = "description_sort", analyze = Analyze.NO, store = Store.YES)
    })
    @ContainedIn
    @Column(name = "description")
    public String getDescription() {
        return description;
    }
    ...
}

以及索引方法如下:

fullTextEntityManager.createIndexer()
    .purgeAllOnStart(true)
    .optimizeAfterPurge(true)
    .optimizeOnFinish(true)
    .batchSizeToLoadObjects(25)
    .threadsToLoadObjects(8)
    .startAndWait();


推荐答案

您错误地放置了ContainedIn注释。根据Hibernate Search文档:

You placed ContainedIn annotation incorrectly. According the Hibernate Search documentation:


小心。因为在使用@InededEmbedded技术时,Lucene索引中的数据是非规范化的,所以Hibernate Search需要知道Place对象的任何更改以及Address对象中的任何更改,以使索引保持最新。为确保Place Lucene文档在地址更改时更新,您需要使用@ContainedIn标记双向关系的另一面。

Be careful. Because the data is denormalized in the Lucene index when using the @IndexedEmbedded technique, Hibernate Search needs to be aware of any change in the Place object and any change in the Address object to keep the index up to date. To make sure the Place Lucene document is updated when it's Address changes, you need to mark the other side of the bidirectional relationship with @ContainedIn.

在您的示例中,您需要:

In your example, you need to:


  1. 使类之间的关系双向化

  2. Mark ClassB中的关系为ContainedIn

在您的情况下:

ClassB {

    private Set<ClassA> linkedObjects;

    .... 

    @OneToMany(mappedBy="place")
    @ContainedIn
    public Set<ClassA> getLinkedObjects() {
        return linkedObjects;
    }

    ....
}

这篇关于外部实体更改后索引不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆