Following this example: Spring Data JPA Batch Inserts, I have created my own way of updating it without having to deal with EntityManager.
The way I did it is first to retrieve all the data that I want to update, in your case, it will be WHERE goodsId=:goodsId AND level=:level. And then I use a for loop to loop through the whole list and setting the data I want
List<GoodsPrice> goodsPriceList = goodsRepository.findAllByGoodsIdAndLevel();
for(GoodsPrice goods : goodsPriceList) {
goods.setPrice({{price}});
}
goodsRepository.saveAll(goodsPriceList);
Some of the followings are needed for inserts or updates. Having generate_statistics on so that you can see if you are really batching it
// for logging purpose, to make sure it is working
spring.jpa.properties.hibernate.generate_statistics=true
// Essentially key to turn it on
spring.jpa.properties.hibernate.jdbc.batch_size=4
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
and the log is here
27315 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
603684 nanoseconds spent preparing 4 JDBC statements;
3268688 nanoseconds spent executing 3 JDBC statements;
4028317 nanoseconds spent executing 2 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
6392912 nanoseconds spent executing 1 flushes (flushing a total of 3 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
void batchUpdate(@Param("price") Double price, @Param("goodsId ") Long goodsid, @Param("level") Long level);