使用Hibernate进行批量保存的更快方法?

Jam*_*ams 3 java hibernate batch-file

我有一个程序,它逐行读取文本文件,并从每一行创建一个Hibernate实体对象,并保存它们.我有几个这样的文本文件要处理,每个文件都有大约300,000行.我发现我目前的实施速度非常慢,而且我想知道我能做些什么来改进.

我的main方法逐行处理文本文件,如下所示:

// read the file line by line
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
int lineCount = 0;
String line = bufferedReader.readLine();
while (line != null)
{
    // convert the line into an Observations object and persist it
    convertAndPersistObservationsLine(line);

    // if the number of lines we've processed has built up to the JDBC batch size then flush
    // and clear the session in order to control the size of Hibernate's first level cache
    lineCount++;
    if (lineCount % JDBC_CACHE_SIZE == 0)
    {
        observationsDao.flush();
        observationsDao.clear();
    }

    line = bufferedReader.readLine();
}
Run Code Online (Sandbox Code Playgroud)

convertAndPersistObservationsLine()方法只是将文本行拆分为标记,创建一个新的实体对象,使用来自标记的数据填充实体的字段,然后通过调用Hibernate的Session.saveOrUpdate()方法的DAO保存对象.DAO方法flush()和clear()是对相应Hibernate Session方法的直接调用.

Hibernate属性'hibernate.use_second_level_cache'设置为false,Hibernate属性'hibernate.jdbc.batch_size'设置为50,Java常量JDBC_CACHE_SIZE也是如此.

有人可以建议一个更好的方法来解决这个问题,或者对上面的任何调整可能会改善这个批量加载程序的性能吗?

在此先感谢您的帮助.

- 詹姆士

Pas*_*ent 8

代码本身和Hibernate配置看起来是正确的(通过正确我的意思是它们遵循文档中的批量插入惯用法).但是这里有一些额外的建议:

如前所述,使绝对确保你没有使用一个ID生成器,击败配料一样IDENTITY.使用时GenerationType.AUTO,持久性提供程序将根据数据库选择适当的策略,因此,根据您的数据库,您可能需要更改TABLE或使用SEQUENCE策略(因为Hibernate可以使用hi-lo算法缓存ID).

还要确保Hibernate按预期进行批处理.为此,请激活日志记录并监视其BatchingBatcher以跟踪正在执行的批处理的大小(将被记录).

在您的特定情况下,你实际上可能会考虑使用StatelessSession接口(一旦问题将得到解决,当然).