Пакетные вставки с JPA / EJB3 - PullRequest
       13

Пакетные вставки с JPA / EJB3

21 голосов
/ 15 января 2009

Предоставляет ли среда JPA / EJB3 стандартный способ выполнения операции пакетной вставки ...? Мы используем hibernate для постоянных фреймворков, поэтому я могу вернуться к Hibernate Session и использовать комбинацию session.save () / session.flush () для достижения пакетной вставки. Но хотелось бы знать, есть ли в EJB3 поддержка для этого ...

Ответы [ 5 ]

21 голосов
/ 02 сентября 2010

Ни JPA, ни Hibernate не предоставляют особой поддержки для пакетных вставок, и выражение для пакетных вставок с JPA будет таким же, как с Hibernate:

EntityManager em = ...;
EntityTransaction tx = em.getTransaction();
tx.begin();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    em.persist(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        em.flush();
        em.clear();
    }
}

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

Использование собственного API Hibernate в этом случае не дает никаких преимуществ IMO.

Ссылки

  • JPA 1.0 Технические характеристики
    • Раздел 4.10 «Операции массового обновления и удаления»
  • Справочное руководство по Hibernate Core
5 голосов
/ 15 января 2009

Специально для hibernate, вся глава 13 основного руководства объясняет методы.

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

В EJB речь идет просто об использовании EJB-QL (с некоторыми ограничениями). Hibernate предоставляет больше механизмов, если вам нужна большая гибкость.

4 голосов
/ 03 апреля 2014

При среднем количестве записей вы можете использовать этот способ:

em.getTransaction().begin();
for (int i = 1; i <= 100000; i++) {
     Point point = new Point(i, i);
     em.persist(point);
     if ((i % 10000) == 0) {
          em.flush();
          em.clear();
     }
}
em.getTransaction().commit();

Но при большом количестве записей вы должны выполнить эту задачу в нескольких транзакциях:

em.getTransaction().begin();
for (int i = 1; i <= 1000000; i++) {
      Point point = new Point(i, i);
      em.persist(point);
      if ((i % 10000) == 0) {
          em.getTransaction().commit();
          em.clear();          
          em.getTransaction().begin();
      }
}
em.getTransaction().commit();

Ссылка: JPA Batch Store

1 голос
/ 13 декабря 2013

Паскаль

В вашем примере для вставки 100000 записей это делается в рамках одной транзакции, так как commit () вызывается только в конце. Оказывает ли это большое давление на базу данных? Кроме того, в случае отката стоимость будет слишком высокой.

Будет ли следующий подход лучше?

EntityManager em = ...;
for ( int i=0; i<100000; i++ ) {
   if(!em.getTransaction().isActive()) {
      em.getTransaction().begin();
   }
   Customer customer = new Customer(.....);
   em.persist(customer);
   if ((i+1) % 20 == 0 ) { //20, same as the JDBC batch size
      //flush and commit of inserts and release memory:
      em.getTransaction().commit(); 
      em.clear();
   }
}

session.close();
1 голос
/ 06 июля 2009

Да, вы можете вернуться к реализации JPA, если хотите, чтобы у вас был определенный вами элемент управления.

JPA 1.0 богат на EL-HQL, но немного поддерживает Criteria API, однако это было исправлено в 2.0.

Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...