java - 外部实体更改后索引不更新

标签 java jpa indexing hibernate-mapping hibernate-search

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

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

但是,当我将 classB 的值 description 从“someStr”更改为“anotherStr”时。数据库相应地更新了,但是当我使用Luke检查索引时,索引中的classA.classB.description没有更新,并且数据不能通过关键字“anotherStr”搜索到,但可以通过关键字“someStr”搜索到。

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

根据 Hibernate 搜索网站,

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.

但这对我来说不起作用。我不确定我是否遗漏了一些细节,或者我需要自己处理此类问题。

我还尝试按照 this one 的建议在 classB 上添加注释 @Indexed ,但它仍然没有解决我的问题。

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

谁能给些建议?谢谢。

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

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 搜索文档:

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.

在您的示例中,您需要:

  1. 使类之间的关系是双向的
  2. 将ClassB中的关系标记为ContainedIn

在你的情况下:

ClassB {

    private Set<ClassA> linkedObjects;

    .... 

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

    ....
}

关于java - 外部实体更改后索引不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23136352/

相关文章:

Java 构造函数与内联字段初始化

hibernate - JPA 相关子查询中缺少 "from"

Java 重写抽象接口(interface)方法

Java 矩阵对角差 bug

java - 将列映射到映射 hibernate

java - session#refresh 不使用@ManyToOne 和复合键刷新根实体

MySQL 索引 - 如何提高性能?

android - AOSP/Android 源码索引工具

sql - 如何在可能具有空值的字段上创建唯一索引 (Oracle 11g)?

java - 检查大小然后执行操作 - ConcurrentLinkedDeque 是否安全?