Java Hibernate JDBC批处理大小不起作用
我在jpa中使用SpringFramework3、Hibernate4和MySQL5。我的测试代码看起来像Java Hibernate JDBC批处理大小不起作用,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,我在jpa中使用SpringFramework3、Hibernate4和MySQL5。我的测试代码看起来像 @Repository public class TestRepositoryImpl implements TestRepository { @PersistenceContext private EntityManager em; @Override @Transactional public void insertBulk() { Item it;
@Repository
public class TestRepositoryImpl implements TestRepository {
@PersistenceContext
private EntityManager em;
@Override
@Transactional
public void insertBulk() {
Item it;
for(int i= 0; i<1000;i++) {
it = new Item();
it.setPrice(Math.random()*100);
em.persist(it);
}
}
}
@存储库
公共类TestRepositoryImpl实现TestRepository{
@持久上下文
私人实体管理者;
@凌驾
@交易的
公共void insertBulk(){
项目it;
对于(int i=0;i您误解了“批量大小”。批量大小表示发送“批量大小”一次查询的数量,而不是在代码触发查询时发送每个查询。因此,在这种情况下,将有1000个insert查询,发送50次,每个批中有20个insert查询。请注意,如果插入表的主键是GEN,Hibernate将在JDBC级别透明地禁用插入批处理erationType.Identity
save()只需一条记录,然后flush(),因此每次刷新只需处理一个追加插入SQL。这就是为什么Hibernate无法帮助您批插入,因为只需处理一个插入SQL。在调用flush()之前,您应该将()保存到一定数量的记录,而不是每次save()都调用flush()
批量插入的最佳实践如下:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<888888; i++ ) {
TableA record = new TableA();
record.setXXXX();
session.save(record)
if ( i % 50 == 0 ) { //50, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
Session Session=sessionFactory.openSession();
事务tx=会话.beginTransaction();
对于(inti=0;i在调试级别添加记录器org.hibernate.engine.jdbc.batch.internal.BatchingBatch
。
如果插入顺序错误,hibernate可以生成大小为1或2的批。
尝试使用hibernate.order\u inserts=true hibernate.order\u updates=true
请添加堆栈跟踪sorry…此代码中没有异常或任何错误。代码工作正常,但在控制台上打印1000次insert查询。我想这样做,您的代码片段工作正常。但我认为此代码是特定于hibernate的代码,我想使用jpa不是特定于hibernate的。可能是我的jpa是hibernate、eclipselink或openjpa的提供商之一。请检查此问题,了解hibernate在使用identity id generator时禁用批量更新的原因以及您可以执行的操作:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="application" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.springapp.test.domain.Item</class>
<class>com.springapp.test.domain.Order</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/testdb" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.jdbc.batch_size" value="20" />
</properties>
</persistence-unit>
</persistence>
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<888888; i++ ) {
TableA record = new TableA();
record.setXXXX();
session.save(record)
if ( i % 50 == 0 ) { //50, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();