Hibernate Session.SaveOrUpdate метод вызывает select перед каждым элементом - есть ли способ пакетного выбора? - PullRequest
3 голосов
/ 16 ноября 2011

Я использую Java / Hibernate / MySQL. Я создаю список объектов, которые я хочу сохранить в базе данных. Некоторые из предметов являются новыми, а некоторые уже находятся в базе данных (я не знаю, какие именно). По этой причине я использую метод session.SaveOrUpdate, и он отлично работает, вставляя при необходимости и обновляя при необходимости.

Проблема в том, что каждый раз, когда я вызываю saveOrUpdate (myObject), я вижу, что есть вызов select, чтобы проверить, существует ли эта запись, поэтому, если я перебираю N объектов, у меня N запросов select. Можно ли как-нибудь объединить эти выборки вместе?

Влияет ли это поведение на производительность?

Спасибо

журнал, который я получаю:

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 ]

1 голос
/ 16 ноября 2011

Ну, во-первых, эти выборки, а что нет, выполняются в одной транзакции, поэтому они должны работать довольно быстро. Причиной их получения может быть тот факт, что для существующей записи Hibernate, возможно, захочет сначала проверить поле версии (сравнивая его текущее значение с тем, которое уже есть в базе данных), и это выдаст выбор перед обновлением. Более подробную информацию о поведении saveOrUpdate можно найти здесь

Я не думаю, что у вас есть способ контролировать или группировать эти выборки в этом контексте. То, что вы можете сделать для более эффективной работы, выглядит примерно так:

  • у вас есть Список экземпляров сущностей, вы хотите сохранить их текущее состояние в БД, и вы не знаете / не заботитесь, какие из них уже сохранили состояние в БД, а какие новые
  • в данной транзакции вы повторно присоединяете все эти экземпляры к текущему сеансу Hibernate, используя Session.merge(obj)
  • теперь вы можете просто внести необходимые изменения в каждый из этих экземпляров (т.е. в соответствии с вашими потребностями бизнес-логики). Вам больше не нужно вызывать какие-либо методы persist / update для них, чтобы изменения были сохранены в БД, это произойдет автоматически при фиксации транзакции.
0 голосов
/ 16 ноября 2011

Можете ли вы опубликовать наш файл сопоставления?Это может быть связано со свойством ' select-before-update ' в true.По умолчанию это ложь.Если это действительно неверно и вы используете оптимистическую блокировку, выбор не произойдет до обновления.Проверьте это , в котором объясняется оптимистическая блокировка в Hibernate и как происходят обновления.

...