Reputation: 477
I'm using MySQL as my backend and i went through the post Hibernate disabled insert batching when using an identity identifier generator to figure out batch insert is not a viable option with GenerationType.IDENTITY
Also figured that GenerationType.TABLE
performs poorly based on this article & GenerationType.SEQUENCE
is not viable as MySQL doesn't support sequence.
My app heavily uses Spring data JPA and most primary keys are generated via MySQL's AUTO_INCREMENT
& mapped with IDENTITY strategy in the entity. I have usecase to bulk insert records (typically 500 records to atmost 10000). I have seen suggestions on using jOOQ and would like to avoid bringing in a whole new framework just for this purpose.
As a work around, I came up with my own custom solution, although not the most elegant. Some preliminary tests revealed it can perform faster compared to JpaRepository.saveAll()
(without batching) but i may be overlooking other implications. Would this be better than not having batching at all ?
New interface to expose bulk insert option:
public interface MyCustomRepository {
void bulkInsert(List<MyEntity> entities);
}
public interface MyRepository extends JpaRepository<MyEntity, Long>, MyCustomRepository {
}
public class MyCustomRepositoryImpl implements MyCustomRepository {
@PersistenceContext
private EntityManager em;
@Transactional
@Override
public void bulkInsert(List<MyEntity> entities) {
List<List<MyEntity>> batchedList = Lists.partition(entities, batchSize);
batchedList.stream().forEach(list -> {
StringBuffer builder = new StringBuffer();
builder.append("INSERT into my_entity (column1, column2, column3) values ");
builder.append(list.stream().map(myEntity -> {
StringBuilder builder1 = new StringBuilder();
builder1.append("(");
builder1.append(myEntity.getColumn1() + ",");
builder1.append(myEntity.getColumn2() + ",");
builder1.append(myEntity.getColumn3());
builder1.append(")");
return builder1.toString();
}).collect(Collectors.joining(", ")));
em.createNativeQuery(builder.toString()).executeUpdate();
});
}
}
Upvotes: 2
Views: 1213
Reputation: 91
In addition to yours(hibernate), you can use the JDBC template or query DSL-SQL. To see how to implement using query DSL-SQL click here. For the JDBC template click here.
If you need type-safe, easy to code choose query DSL-SQL else choose JDBC template
Upvotes: 0
Reputation: 81862
The implication of this approach is that your entities are still detached from the persistent context and the created id is not set on the entities.
If that is fine for you, this is a fine approach.
Upvotes: 1