我目前正在开发一个项目,用JPA 2.1保存数据,并使用hibernate search 4.5.0.final搜索实体。
映射类和索引后,搜索工作正常。
但是,当我将classB的值 description 从“someStr”更改为“anotherStr”时。数据库已相应更新,但是当我使用Luke检查索引时,索引中的classA.classB.description未更新,并且数据无法通过关键字“anotherStr”进行搜索,但可以通过关键字“someStr”进行搜索。
在重新索引整个数据库之后,它最终会更新。
根据Hibernate搜索网站,
简短的回答是索引是自动的:Hibernate Search将透明地索引通过Hibernate ORM持久化,更新或删除的每个实体。它的任务是保持索引和数据库同步,让你忘记这个问题。
但它不适用于我的情况。我不确定我是否错过了一些细节,或者我需要自己处理这类问题。
我还尝试按照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();
答案 0 :(得分:0)
您错误地放置了ContainedIn注释。根据Hibernate Search文档:
小心点。因为在使用@InededEmbedded技术时,Lucene索引中的数据是非规范化的,所以Hibernate Search需要知道Place对象的任何更改以及Address对象中的任何更改,以使索引保持最新。为确保Place Lucene文档在地址更改时更新,您需要使用@ContainedIn标记双向关系的另一面。
在您的示例中,您需要:
在你的情况下:
ClassB {
private Set<ClassA> linkedObjects;
....
@OneToMany(mappedBy="place")
@ContainedIn
public Set<ClassA> getLinkedObjects() {
return linkedObjects;
}
....
}
答案 1 :(得分:0)
我有类似的问题,但已经有正确的注释。就我而言,我已经将强制刷新添加到数据库中,然后对其进行索引和刷新:
myEm.flush();
Search.getFullTextEntityManager(myEm).flushToIndexes();
myEm.refresh(updatedObject);
答案 2 :(得分:-1)