[英]Java Bulk Insert with Shared Entity Manager
我正在尝试编写一种将实体批量添加到数据库的方法。 这是我的方法:
@Transactional
protected void bulkInsert(List<?> entities) {
int batchSize = 25;
AtomicInteger i = new AtomicInteger(0);
try {
em.getTransaction().begin();
entities.parallelStream().forEach(e -> {
em.persist(e);
if ( i.get() > 0 && i.get() % batchSize == 0 ) {
em.flush();
em.clear();
}
i.incrementAndGet();
});
em.getTransaction().commit();
} catch (RuntimeException e) {
LOG.error("Error", e);
} finally {
if (em != null) {
em.close();
}
}
}
但是当我运行它时,出现以下错误:
java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:248) ~[spring-orm-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at com.sun.proxy.$Proxy145.getTransaction(Unknown Source) ~[na:na]
我尝试删除@Transactional
批注,但仍然是相同的错误。 我尝试通过执行Session session = em.unwrap(Session.class);
使用Session Session session = em.unwrap(Session.class);
但这仍然导致错误(尽管有不同的错误)
如何批量插入对象?
在纯休眠状态下,存在托管和非托管环境
非托管环境
如果JPA持久层在非托管环境中运行,则数据库>连接通常由>场景后面的Hibernate的池化机制处理。 通用实体管理器和事务处理习惯用法如下所示:
//非托管环境习语
EntityManager em = emf.createEntityManager(); EntityTransaction tx = null; 尝试{tx = em.getTransaction(); tx.begin();
// do some work ... tx.commit(); } catch (RuntimeException e) { if ( tx != null && tx.isActive() ) tx.rollback(); throw e; // or display error message } finally { em.close(); }
使用JTA如果使用bean管理的事务(BMT),代码将如下所示:
// BMT成语@Resource public UserTransaction utx; @Resource公共EntityManagerFactory工厂;
公共无效doBusiness(){EntityManager em = factory.createEntityManager(); 尝试{
// do some work ... utx.commit(); } catch (RuntimeException e) { if (utx != null) utx.rollback(); throw e; // or display error message } finally { em.close();
}
使用EJB3容器中的容器管理的事务(CMT),事务>分界是在会话bean注释或部署描述符中完成的,而不是通过编程实现的。 事务完成时,将自动刷新EntityManager(如果您已注入或查找EntityManager,它也将自动关闭)。 如果在使用EntityManager的过程中发生异常,那么如果您没有捕获到异常,则事务回滚会自动发生。 由于EntityManager异常是RuntimeException,因此它们将根据EJB规范回滚事务(系统异常与应用程序异常)。
您应该跟随两个王子。
注解@Transactional是春天的annotaniot不休眠。 如果您没有配置它(或您已经配置了spring),则无法使用。
个人电脑
EntityManager是廉价的,非线程安全的对象,对于单个业务流程应使用一次
调用em.flush(),em.clear()可能很危险。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.