Hibernate Session.SaveOrUpdate方法在每个项目之前调用select - 有没有办法批处理这些选择?

时间:2011-11-16 13:13:23

标签: java mysql hibernate batch-processing

我正在使用java / hibernate / mysql。我正在创建一个我想要保存到数据库的对象列表。有些项目是新的,有些项目已经在数据库中(我不知道哪些项目)。因此我使用session.SaveOrUpdate方法,必要时可以正常插入并在必要时进行更新。

问题是我每次调用saveOrUpdate(myObject)时都会看到有一个select调用来检查这条记录是否已经存在,所以如果我遍历N个对象我有N - 选择查询。有什么方法可以将这些选择一起批处理吗?

此行为是否会对性能产生重大影响?

由于

我得到的日志是:

Hibernate: select price0_.product_id as product1_3_0_, price0_.store_id as 
store2_3_0_, price0_.date_updated as date3_3_0_, price0_.price as price3_0_, 
price0_.quality as quality3_0_, price0_.update_source as update6_3_0_ 
from realworld.price price0_ where price0_.product_id=? and price0_.store_id=?

Hibernate: select price0_.product_id as product1_3_0_, price0_.store_id as 
store2_3_0_, price0_.date_updated as date3_3_0_, price0_.price as price3_0_, 
price0_.quality as quality3_0_, price0_.update_source as update6_3_0_ 
from realworld.price price0_ where price0_.product_id=? and price0_.store_id=?

Hibernate: insert into realworld.price 
(date_updated, price, quality, update_source, product_id, store_id) 
values (?, ?, ?, ?, ?, ?)  

Hibernate: insert into realworld.price 
(date_updated, price, quality, update_source, product_id, store_id) 
values (?, ?, ?, ?, ?, ?)

生成此代码的代码是:

for (Price price : prices){
        HibernateCurrentSession.currentSession().merge(price); 
        i++;
        if ( i % batchsize == 0 ) { 
            //flush a batch of inserts and release memory:
            HibernateCurrentSession.currentSession().flush();
            HibernateCurrentSession.currentSession().clear();
        }

}

2 个答案:

答案 0 :(得分:1)

嗯,首先,那些选择和什么都没有在同一个事务中执行所以它们应该工作得非常快。您得到它们的原因可能是,对于现有条目,Hibernate可能希望首先检查版本字段(通过将其当前值与数据库中已有的值进行比较),这将在更新之前发出选择。有关saveOrUpdate行为的更多详细信息,请参见here

我认为您无法在此上下文中控制或批量选择这些选项。你能做些什么来提高效率是这样的:

  • 你有一个实体实例列表,你想将它们的当前状态保存到数据库,你不知道/关心哪些已经持有状态到db并且哪些是新的
  • 在给定的事务中,使用Session.merge(obj)
  • 将所有这些实例重新附加到当前的Hibernate会话
  • 现在您可以简单地对每个实例进行必要的修改(I.E.根据您的业务逻辑需求)。您不再需要对它们调用任何持久化/更新方法,以便将modif持久保存到db,这将在提交事务时自动发生。

答案 1 :(得分:0)

您可以发布我们的地图文件吗?这可能是因为属性“select-before-update”为真。默认情况下为false。如果这确实是假的并且您正在使用乐观锁定,则在更新之前不会选择。检查this,它解释了Hibernate中的乐观锁定以及更新的发生方式。