首页 > 解决方案 > Spring DAO rewritebatchedstatements 不适用于具有 embeddedId 的实体上的 SaveAll()

问题描述

我们需要在mysql上快速插入 500 万条记录(对此实例没有控制)。

尝试了以下所有方法,但没有任何效果:

  1. 设置rewritebatchedstatements=true(通过 url 和 props)
  2. 试过useServerPrepStmts=trueuseServerPrepStmts=true
  3. 尝试了以下其他休眠道具
  4. Story有所以GenerationType.Auto没关系,但是批处理应该有效吗?(因为没有指定代)TaskEmbeddedId
  5. 试过MySql5InnoDBDialectMySql5DBDialect

批处理工作(基于统计数据)但rewritebatchedstatements不工作。

spring.jpa.properties.hibernate.jdbc.batch_size=500
spring.jpa.properties.hibernate.jdbc.fetch_size=500
spring.jpa.properties.hibernate.jdbc.order_inserts=500
spring.jpa.properties.hibernate.jdbc.order_updates=500

spring.jpa.properties.hibernate.batch_versioned_data=true
spring.jpa.properties.hibernate.generate_statistics=true

spring.datasource.hikari.data-source-properties.rewriteBatchedStatements=true
#spring.datasource.hikari.data-source-properties.useServerPrepStmts=true
spring.datasource.hikari.data-source-properties.useServerPrepStmts=false

示例实体:

class SprintService {

   @Transactional
    public void startSprint(Epic epic, List<Stories> stories) {
        epic.save()
        .....
        stories.saveAll() // few hundreds of records
        Set<Task> tasks = new HashSet<>;
        for(Story story: stories)
        {
            tasks.addAll(story.getTasks());
            tasks.addAll(story.getTasks());
            tasks.addAll(story.getTasks());
            //do something
        }
        tasks.saveAll() // few million records
    }
}

@Table(name = "STORY")
@EqualsAndHashCode
class Story {
   @Id
   @GeneratedValue(stratergy=GenerationType.Auto)
   @Column(name="STORY_ID")
   Long id;

   @Column(name="STORY_NAME")
   String name;

   @OneToMany(cascade=MERGE, mappedBy="story", fetch = FetchType.Lazy)
   Set<Task> task;
}



@Entity
@Table(name = "TASK_XREF")
class Task {
    @EmbeddedId
    TaskPKId taskPKId;

    @Column(name = "TASK_NAME")
    String name;
    @MapsId("storyId")
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "STORY_ID")
    Story story;

    //getters, setters

}

这是 TaskPKID 类:

@Embeddable
class TaskPKId  implements Serializable {
        long taskId;
        long taskTypeId;
        @Column(name="STORY_ID")
        long storyId;

    public long getTaskId() {
        return taskId;
    }

    public void setTaskId(long taskId) {
        this.taskId = taskId;
    }

    public void setTaskTypeId(long taskTypeId) {
        this.taskTypeId = taskTypeId;
    }
}

标签: mysqlhibernatespring-bootspring-data-jpa

解决方案


这些值应该是布尔值。

spring.jpa.properties.hibernate.jdbc.order_inserts=true
spring.jpa.properties.hibernate.jdbc.order_updates=true

推荐阅读