2011-01-03 2 views
11

Я использую hibernate + play! рамки на работе, есть ли «лучшая практика» по вложению большого количества записей с использованием спящего режима? Они составляют от 6 000 до 10 000 в текстовом файле, поэтому я не знаю, собирается ли Hibernate задушить работу или выбросить исключение.Лучший способ вставить хорошее количество записей в спящий режим

Любое предложение, дайте мне знать, дайте мне знать, если я должен объяснить более

ответ

23

С * Java Persistence и Hibernate»(Manning) и после комментария от Пангеи, используйте сессионные (который не имеет кэш контекста живучесть):

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) { 
    Item item = new Item(...); 
    session.insert(item); 
} 
tx.commit(); 
session.close(); 
+4

Я бы не использовал сессию для массовых операций. StatelessSesssion предназначен для массовых операций, таких как это, поскольку он не поддерживает кеш первого уровня: измените «sessionFactory.openSession()» на «sessionFactory.openStatelessSession()». Прочтите раздел «13.3» отсюда http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html –

+0

Спасибо, Пангея, я не знал этого. – Kartoch

+0

Я не уверен, что session session.clear() необходимо сохранить в этом примере: нет необходимости высекать все объекты из кеша сеанса, потому что нет кеша с сеансом без состояния. Я напишу это в источнике ... – Kartoch

1

Просто откройте сеанс и транзакции.

Добавить все элементы в сохранение сеанса.

Затем совершите транзакцию.

//Remember to effective handler errors 
public void saveAll(List<Object> list) throws Exception{ 
Session s = HibernateUtil.openSession(); 
Transaction tx = s.beginTransaction(); 
for(Object obj : list) 
s.save(obj); 
tx.commit(); 
s.flush(); 
s.close(); 
} 
+3

Пожалуйста, не делайте этого. Для пакетных транзакций лучше избегать кеширования сеансов, иначе вы столкнетесь с исключением OOM. Для этого конкретного сценария существует StatelessSession, о чем упоминает Пангея в ответе Картоха. – jpkrohling

-5

Вы можете всегда получить объект подключения непосредственно в случае, если вы хотите, чтобы сделать вставки вне спящего режима.

Connection connection = DB.getConnection(); 
+1

Не могли бы вы объяснить, как это решит проблему? – Phani

1

Лучше всего использовать StatelessSessions. Рассмотрим следующий пример из (http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html):

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 

ScrollableResults customers = session.getNamedQuery("GetCustomers") 
    .scroll(ScrollMode.FORWARD_ONLY); 
while (customers.next()) { 
    Customer customer = (Customer) customers.get(0); 
    customer.updateStuff(...); 
    session.update(customer); 
} 

tx.commit(); 
session.close(); 
2

Просто некоторые исправления кодов в ответе Картоха.

В соответствии с Batch Procession «Операции insert(), update() и delete(), определенные интерфейсом StatelessSession, рассматриваются как прямые операции на уровне строки базы данных. Они приводят к немедленному выполнению SQL INSERT, UPDATE или DELETE соответственно. Они имеют разную семантику операций save(), saveOrUpdate() и delete(), определенных интерфейсом сеанса. "

Больше нет save(), flush(), clear() для StatelessSession. Код должен выглядеть так:

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 

for (int i=0; i<100000; i++) { 
    Item item = new Item(.....); 
    session.insert(item); 
}  

tx.commit(); 
session.close(); 

Наконец, здесь идет обсуждение разницы между обычной пакетной вставки и StatelessSession вставки: Using StatelessSession for Batch processing.

Смежные вопросы