我正在 Glassfish 3.1.2.2、EclipseLink 2.3.2 上编写 JPA 应用程序。我也在使用 Spring MVC,使用容器管理的 EntityManager(@PersistenceContext
由 Spring 注入,但由容器通过创建jee:jndi-lookup
)
我在persistence.xml 中设置eclipselink.jdbc.batch-writing
,JDBC
但它没有按预期工作。
我的代码有一个相当简单的循环来编写一堆对象
UserTransaction tx = ...;
tx.begin();
for (MyObject obj : list) {
entityManager.persist(obj);
}
tx.commit();
如果我用方法周围的注释替换 UserTransaction ,批量写入确实有效!@Transactional
我看到为每个持久调用创建了一个单独的工作单元:
FINER: client acquired: 3418589
FINER: TX binding to tx mgr, status=STATUS_ACTIVE
FINER: acquire unit of work: 11053522
FINEST: persist() operation called on: mypkg.MyClass@1252ed8
....
FINER: client acquired: 23361578
FINER: TX binding to tx mgr, status=STATUS_ACTIVE
FINER: acquire unit of work: 17636998
FINEST: persist() operation called on: mypkg.MyClass@1252ed8
正如预期的那样,在提交之前,数据库操作实际上不会执行 - 但每个工作单元都有自己的批次:
FINER: TX beforeCompletion callback, status=STATUS_ACTIVE
FINER: begin unit of work commit
FINER: TX beginTransaction, status=STATUS_ACTIVE
FINEST: Execute query InsertObjectQuery(mypkg.MyClass@12a46ef)
FINEST: Connection acquired from connection pool [default].
FINEST: Execute query
FINER: Begin batch statements
FINE: INSERT INTO ....
FINE: bind => [24 parameters bound]
FINER: End Batch Statements
有什么我想念的想法吗?我认为问题的根源是每个持久化的单独工作单元。
注意我确实看到在单个工作单元中通过单个持久性级联的子实体的批处理工作。但是每组父/子都是一个单独的批次。