我目前正在开展一个项目,以使用 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.
在您的示例中,您需要:
- 使类之间的关系是双向的
- 将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/