我一直在使用Hibernate使用@OneToMany与@JoinColumn存储父子关系已经有一段时间了,它运行得很好。
但是现在我已经达到了一个对象的总大小太大而不适合记忆的程度。 (例如,现在有300万个儿童记录)。记录都存储在一个文件中,然后在被休眠之前解析为Java对象。
我想“分块”或“批量”记录,这样我一次只需要将其中的一小部分读入内存。我的方法类似于“加载10,000个子对象的集合,持久化到数据库(在父obj上调用'update'),清空子集合以释放RAM,重复”。
我想要这样工作:
Iteration 1: Chunk1 (records 1-10,000) stored
Iteration 2: Chunk2 (records 10,001-20,000) stored
Iteration 3: Chunk3 (records 20,001-30,000) stored
etc
这是我遇到麻烦的地方。我保存的集合随着每次迭代而变化,这会导致hibernate在保存新子节点之前删除所有旧子节点。我最终没有得到我的所有部分,而是
Iteration 1: Chunk1 stored
Iteration 2: Chunk1 objects deleted, Chunk 2 stored
Iteration 3: Chunk2 objects deleted, Chunk 3 stored
etc
所以最后,只保存了我的最后一块。
有没有办法改变这种行为?我已经阅读过有关JDBC批处理的内容,但这并不是我正在寻找的内容。我也尝试分别存储每个Child,而不是通过“更新”到父级,但是当我这样做时,子记录被持久化而没有指向父级的指针。
更新
感谢快速而极好的回应。这种关系不是双向的 - 我会尝试这样做。我有遗留代码,不会与架构更改配合,因此有点受限制。
由于
答案 0 :(得分:2)
这里的主要问题是:你的关系是双向的吗?也就是说,你在孩子那边有一个@ManyToOne
指向父母吗?
如果你这样做,那种关系需要由孩子一方拥有:
// in Parent
@OneToMany(mappedBy="parent")
List<Child> getChildren();
// in Child
@ManyToOne
Parent getParent();
当以这种方式设置时, NOT 需要加载父集合中的所有(或任何)子项 - 您可以改为加载(或创建)子项,设置父项结束并拯救他们;你当然可以批量做。
如果您的关系不双向,那么根据您的问题,它由父母拥有 - 您需要将其设为双向,如上所示(或单向,但与现在相反 - 见下文。
在一个单独的说明中,你甚至需要在父方面@OneToMany
吗?有300万儿童记录,我无法想象它在哪里有用。