Java 如何加速Hibernate批处理并避免OutOfMemoryException
说明 我有一个Spring应用程序,它使用Hibernate ORM与数据库通信。我有这个函数,它填充名为orders、order_line和cc_xacts的数据库表。各表之间的关系如下所示:Java 如何加速Hibernate批处理并避免OutOfMemoryException,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,说明 我有一个Spring应用程序,它使用Hibernate ORM与数据库通信。我有这个函数,它填充名为orders、order_line和cc_xacts的数据库表。各表之间的关系如下所示: -------- -------------- |orders|--- 1:m --->| order_line | -------- -------------- | ------------ --------
-------- --------------
|orders|--- 1:m --->| order_line |
-------- --------------
| ------------
-------- 1:m --->| cc_xacts |
------------
因此订单与cc_xacts和order_line实体有一对多的关系
public void populateOrders和cc_XACTSTable()
{
格列高利安达卡尔;
字符串[]信用卡={“VISA”、“万事达卡”、“发现”、“美国运通”,
“食客”};
int num_卡片类型=5;
字符串[]ship_types={“AIR”、“UPS”、“FEDEX”、“ship”、“COURIER”、“MAIL”};
int num_ship_type=6;
String[]status_types={“PROCESSING”、“SHIPPED”、“PENDING”、“DENIED”};
int num_status_types=4;
//顺序变量
INTO_C_ID;
java.sql.Timestamp O_DATE;
双O_分项合计;
双重营业税;
双O_总数;
字符串O_船舶类型;
java.sql.Timestamp O_SHIP_DATE;
int O_BILL_ADDR_ID,O_SHIP_ADDR_ID;
字符串O_状态;
字符串类型;
int CX_NUM;
字符串名称;
java.sql.Date CX\u到期日;
字符串CX\u AUTH\u ID;
int CX_CO_ID;
System.out.println(“填充订单、订单行、抄送”
+订单数量+“订单”);
系统输出打印(“完成(10000年):”;
对于(int i=1;i使用批处理,例如刷新/提交部分结果,例如每1000次插入提交一次,以减少存储的回滚数据
您需要,因此需要设置以下Hibernate属性:
properties.put("hibernate.jdbc.batch_size", "50");
properties.put("hibernate.order_inserts", "true");
properties.put("hibernate.order_updates", "true");
properties.put("hibernate.jdbc.batch_versioned_data", "true");
若要避免OutOfMemoryError,您需要在批准备刷新时清除当前会话:
doInTransaction(session -> {
int batchSize = batchSize();
for(int i = 0; i < itemsCount(); i++) {
//batch insert logic
if(i % batchSize == 0 && i > 0) {
session.flush();
session.clear();
}
}
});
您可以在开始时获取它们,或者至少将结果缓存在本地映射中。每次选择(如果使用自动刷新),都会降低批处理性能
有时,如果您正在记录hibernate信息并将其打印到控制台,可能会导致从hibernate获取的速度变慢。
您可以关闭将日志打印到控制台我按照您的说明进行了操作,现在速度快多了。谢谢!
doInTransaction(session -> {
int batchSize = batchSize();
for(int i = 0; i < itemsCount(); i++) {
//batch insert logic
if(i % batchSize == 0 && i > 0) {
session.flush();
session.clear();
}
}
});
customerDao.findById( O_C_ID );
countryDao.findById( CX_CO_ID );