Пакетные вставки с JPA / EJB3
Является ли инфраструктура JPA / EJB3 стандартным способом работы с вставкой в пакет …? Мы используем hibernate для платформы persistence, поэтому я могу вернуться на сеанс Hibernate и использовать комбинацию session.save () / session.flush () для достижения пакетной вставки. Но хотелось бы знать, поддерживает ли EJB3 это …
- Как аннотировать поле автоинкремента MYSQL с аннотациями JPA
- Может ли Hibernate работать с синтаксисом «ON DUPLICATE KEY UPDATE» MySQL?
- объект ссылается на несохраненный экземпляр переходного процесса - сохраняет временный экземпляр перед промывкой
- Как вы можете делать пейджинг с NHibernate?
- Должен ли я преобразовывать объекты Entity (Persistent) в объекты DTO?
- LINQ To Entities не распознает метод Last. В самом деле?
- Вычисленное свойство с JPA / Hibernate
- Что такое «постоянство невежества»?
Ни 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
- Глава 13. Пакетная обработка
Для спящего режима, в частности, вся глава 13 основного руководства объясняет методы.
Но вы говорите, что хотите использовать EJB-метод через Hibernate, поэтому документация менеджера объектов также содержит главу о том, что здесь . Я предлагаю вам прочитать как (kernel, так и менеджер сущности).
В EJB это просто об использовании EJB-QL (с некоторыми ограничениями). Hibernate обеспечивает больше механики, хотя, если вам нужна большая гибкость.
С номером средних записей вы можете использовать этот способ:
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
Да, вы можете откатиться к своей реализации JPA, если хотите, чтобы вы определили этот элемент управления.
JPA 1.0 богата на EL-HQL, но облегчает поддержку API Criteria, однако это было рассмотрено в версии 2.0.
Session session = (Session) entityManager.getDelegate(); session.setFlushMode(FlushMode.MANUAL);
паскаль
В вашем примере, чтобы вставить 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();