【发布时间】:2018-12-11 18:04:43
【问题描述】:
我有一个 Spring 应用程序,使用 Hibernate,并通过 Hibernate-Search 连接到 Elasticsearch。
为简化示例,我将只放置所需的注释和代码。
我有一个实体 A,包含在多个 B 实体中(很多,实际上大约 8000 个)。
B 实体还包含许多嵌入的细节(实体 C、E、...)。
这些实体都与 @IndexedEmbedded 和 @ContainedIn Hibernate-Search 注释相关联(参见下面的示例)。
我创建了一个服务,修改了 A 对象的一个字段,并通过 flushToIndexes 强制刷新。
在刷新时,Hibernate-Search 更新 A 索引,并且由于 @ContainedIn,在 8000 个 B 索引上传播。
但是为了更新 B 索引,出于某种原因,Hibernate-Search 会加载每 8000 个链接到 A 对象的 B 对象,
以及那些 B 对象(C、E 等)中包含的所有细节。
所有这一切都需要很长时间,并以 java.lang.OutOfMemoryError: Java heap space 结束。
@Entity
@Table(name = "A")
@Indexed
public class A {
@ContainedIn
@OneToMany(fetch = FetchType.LAZY, mappedBy = "a")
private Set<B> bCollection;
@Field
@Column(name = "SOME_FIELD")
private String someField; // Value updated in the service
}
@Entity
@Table(name = "B")
@Indexed
public class B {
@IndexedEmbedded
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "A_ID")
private A a;
@IndexedEmbedded
@OneToOne(fetch = FetchType.LAZY, mappedBy = "b")
@Fetch(FetchMode.JOIN)
private C c; // Some other details
@IndexedEmbedded
@OneToMany(fetch = FetchType.LAZY, mappedBy = "b")
private Set<E> eCollection; // Some other details
}
// My service
aObject.setSomeField("some value");
fullTextSession.flushToIndexes();
增加 JVM 分配的内存(从 8GB 到 24GB,这实际上对于大约 10000 个对象来说已经很多了)并没有解决任何问题。 所以我假设加载整个数据集需要超过 24 GB...
但是,问题似乎比看起来要复杂〜
那是一个错误吗?这很常见吗?我做错了什么 ?我该如何解决?
是否有一些隐藏的 Hibernate-Search 配置来避免这种行为?
【问题讨论】:
标签: java hibernate-search