Spring Data JPA: Batch insert for nested entities

后端 未结 1 1087
眼角桃花
眼角桃花 2020-11-28 12:47

I have a test case where I need to persist 100\'000 entity instances into the database. The code I\'m currently using does this, but it takes up to 40 seconds until all the

相关标签:
1条回答
  • 2020-11-28 13:24

    Make sure to configure Hibernate batch-related properties properly:

    <property name="hibernate.jdbc.batch_size">100</property>
    <property name="hibernate.order_inserts">true</property>
    <property name="hibernate.order_updates">true</property>
    

    The point is that successive statements can be batched if they manipulate the same table. If there comes the statement doing insert to another table, the previous batch construction must be interrupted and executed before that statement. With the hibernate.order_inserts property you are giving permission to Hibernate to reorder inserts before constructing batch statements (hibernate.order_updates has the same effect for update statements).

    jdbc.batch_size is the maximum batch size that Hibernate will use. Try and analyze different values and pick one that shows best performance in your use cases.

    Note that batching of insert statements is disabled if IDENTITY id generator is used.

    Specific to MySQL, you have to specify rewriteBatchedStatements=true as part of the connection URL. To make sure that batching is working as expected, add profileSQL=true to inspect the SQL the driver sends to the database. More details here.

    If your entities are versioned (for optimistic locking purposes), then in order to utilize batch updates (doesn't impact inserts) you will have to turn on also:

    <property name="hibernate.jdbc.batch_versioned_data">true</property>
    

    With this property you tell Hibernate that the JDBC driver is capable to return the correct count of affected rows when executing batch update (needed to perform the version check). You have to check whether this works properly for your database/jdbc driver. For example, it does not work in Oracle 11 and older Oracle versions.

    You may also want to flush and clear the persistence context after each batch to release memory, otherwise all of the managed objects remain in the persistence context until it is closed.

    Also, you may find this blog useful as it nicely explains the details of Hibernate batching mechanism.

    0 讨论(0)
提交回复
热议问题