Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

Ни 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.

Ссылки

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

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

Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);

Ответ 5

Паскаль

В вашем примере, чтобы вставить 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();