我需要将一个对象插入到具有多个嵌套对象的数据库中,如:
class A{
List<B> b;
}
class B{
List<C> c;
List<D> d;
List<E> e;
}
现在我将有一个A的单个对象持久存在,它将有多个B类型的对象,而B又会有多个C,D和E类型的对象。
可能总共有10,000个B,C,D和E对象组合在一起。我使用以下对hibernate.cfg.xml
的添加配置了批量插入<property name="hibernate.jdbc.batch_size">50</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>
我还添加了
rewriteBatchedStatements=true
在hibernate的connection.url属性中。
我正在为id使用增量生成器。 我会在每个B元素中收到一个A的json以及嵌套的B列表和嵌套的C,D和E.这将转换为对象A并使用
保存到db中session.save(A);
因为我启用了级联,所有嵌套对象都会持久存储到db中。 10,000个对象的总插入时间大约需要25秒。 我不确定批处理是否已启用,因为我看到单个插入语句,如
insert into C(id, val) values(1,"val");
insert into C(id, val) values(2,"val2");
我提到hibernate batch insert doc,它要求我
session.flush();
session.clear();
jdbc批量大小插入后。我不知道如何在我的情况下这样做,我也尝试使用无状态会话,我也没有看到任何改进。关于如何改善性能的任何建议都会很棒。
答案 0 :(得分:0)
如果您稍微改变一下方法,我认为您可以在这里提高性能。因此,您可以单独保存实体,而不是单个级联保存。这假设您已声明了双向关系,如果您希望这样做,我认为您需要这些关系。
因此,从A中删除所有List<T>
,然后单独保存A.
类似的东西:
session.save(a)
session.evict(a)
这意味着A已被持久化但在会话中不再存在。然后,您可以单独保存关联的实体:
for (B b : a.getListOfB()) {
b.setA(a);
session.save(b);
}
如果您愿意,可以刷新并逐出或使用无状态会话。