Java Hibernate JDBC批处理大小不起作用

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;

我在jpa中使用SpringFramework3、Hibernate4和MySQL5。我的测试代码看起来像

@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();