我有一个ItemList
类,其中包含一组Items
,映射如下:
<class name="ItemList">
<id name="PID" column="PID">
<generator class="uuid" />
</id>
<version name="Version" />
<set cascaed="save-update" name="Items">
<key column="itemlist_id" />
<one-to-many class="Item" />
</set>
</class>
<class name="Item">
<id name="PID" column="PID">
<generator class="uuid" />
</id>
...
</class>
这是单向关联。我需要将Items
的1000个批量插入ItemList
。在批量插入上使用hibernate doc,我有类似的东西:
ItemList itemList = ...
int i = 0;
for (Item item : someItems) {
// .. some processing..
itemList.getItems().add(item);
if (++i % 30 == 0) {
session.update(itemList);
session.flush();
session.clear();
}
}
显然存在一些问题。每次冲洗时,插入30个项目。然后更新ItemList的版本。然后使用ItemList的PID更新所有30个项目。
答案 0 :(得分:0)
抱歉,对此无能为力(但为什么要关心?)。
您的意思是每30个项目更新一次?你也不想......除非你愿意冒内存不足的风险,因为所有的Item
都存储在会话级缓存中。
这是有效的,因为Session.flush()
个documentation状态:
Flushing 是同步底层持久性的过程 持久存在的商店。
因此,在冲洗完毕后你已经完成了最后30项,他们就在数据库方面。 然而,并不意味着他们已提交。数据库知道您正处于尚未提交的事务中间。
修改强>
也许我现在意识到为什么版本会在每个flush
之后递增。我在这里猜测。 Hibernate使用version
列来验证,因为事务已经启动,所以没有其他事务更改了当前事务修改的实体。但是这个验证仅代表Hibernate,而不是使用任何数据库固有的功能。我认为这是真的,因为版本表的DDL显示version
列是普通的int
(这也是有意义的,因为Hibernate是一个跨数据库供应商的API,但OTOH他们可以有特定的工具为每个供应商)。因此,在刷新之前,Hibernate最后有机会验证刷新的实体不是陈旧的数据。刷新后,这些更新的实体不再标记为更新,以便即使在同一事务中,将来的刷新也不会触发版本验证事件。