当前位置: 首页 > 知识库问答 >
问题:

Spring Data JPA:嵌套实体的批插入

蒋俊
2023-03-14

我有一个测试用例,需要将100,000个实体实例持久化到数据库中。我当前使用的代码就是这样做的,但直到将所有数据持久化到数据库中为止,最多需要40秒。数据是从一个大约15 MB大小的JSON文件中读取的。

现在,我已经为另一个项目在自定义存储库中实现了批处理插入方法。但是,在这种情况下,我有很多顶级实体要持久化,只有几个嵌套实体。

在我当前的例子中,我有5个job实体,这些实体包含大约30个jobdetail实体的列表。一个JobDetail包含850到1100个JobEnvelope实体。

这是我的三个问题:

@Entity
public class Job {
  @Id
  @GeneratedValue
  private int jobId;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, mappedBy = "job")
  @JsonManagedReference
  private Collection<JobDetail> jobDetails;
}
@Entity
public class JobDetail {
  @Id
  @GeneratedValue
  private int jobDetailId;

  @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
  @JoinColumn(name = "jobId")
  @JsonBackReference
  private Job job;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, mappedBy = "jobDetail")
  @JsonManagedReference
  private List<JobEnvelope> jobEnvelopes;
}
@Entity
public class JobEnvelope {
  @Id
  @GeneratedValue
  private int jobEnvelopeId;

  @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
  @JoinColumn(name = "jobDetailId")
  private JobDetail jobDetail;

  private double weight;
}

共有1个答案

谭泉
2023-03-14

确保正确配置Hibernate批处理相关属性:

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

关键是,如果连续语句操作同一个表,则可以批处理这些语句。如果出现对另一个表执行insert操作的语句,则必须中断前面的批处理构造并在该语句之前执行。通过Hibernate.order_inserts属性,您可以在构造批处理语句之前授予Hibernate权限以重新排序插入(Hibernate.order_updates对update语句具有相同的效果)。

jdbc.batch_size是Hibernate将使用的最大批处理大小。尝试并分析不同的值,选择一个在您的用例中表现出最佳性能的值。

如果您的实体是版本化的(出于乐观锁定的目的),那么为了利用批处理更新(不影响插入),您还必须打开:

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

通过该属性,您可以告诉Hibernate,JDBC驱动程序能够在执行批处理更新(执行版本检查所需的)时返回受影响行的正确计数。您必须检查这对于您的数据库/JDBC驱动程序是否正常工作。例如,它在Oracle 11和更早的Oracle版本中不起作用。

您还可能希望在每个批处理之后刷新和清除持久性上下文以释放内存,否则所有托管对象都将保留在持久性上下文中,直到它关闭为止。

 类似资料:
  • 问题内容: 我有一个测试用例,需要将100‘000个实体实例持久存储到数据库中。我当前使用的代码可以做到这一点,但是要花40秒才能将所有数据持久保存在数据库中。从大小约为15 MB的JSON文件中读取数据。 现在,在另一个项目之前,我已经在自定义存储库中实现了批量插入方法。但是,在那种情况下,我要保留许多顶级实体,而只有少数嵌套实体。 在我目前的情况下,我有5个实体,其中包含约30个实体的列表。其

  • 所以我是spring boot的新手,我遇到了一个小问题,我需要通过POST调用保存2个对象实体。问题是在Object中保存一个嵌套的对象数组。 JSON: 我有两个实体Doctor和Patient具有类构造函数: 没有吸气器和设置器的医生: 和不带吸气器和设置器的病人: 因此,当我将JSON插入POST调用时,我得到以下错误:{“Timestamp”:1613060297379,“Status”

  • 我在我的项目中使用Spring引导和Spring数据,我有两个类: 第二类是: 添加任务的方法: 当我试图添加一个新的任务,它给出了这个错误: “找不到id为2的com.carpooling.entity.Station;嵌套异常为javax.persistence.EntityNotFoundException:找不到id为2的com.carpooling.entity.Station” 下面是

  • 我实现了两个 entites。规则实体和 RestCall 实体如下所示: RuleEntity RestCallEntity 我在 json 终结点中收到一条规则。比我将收到的 json 规则转换为规则实体并调用 当我只是更改规则的名称时,更新工作正常。但是当我更改它的名称时,它看起来像Hibernate尝试创建一个新的重新调用,即使它已经有一个ID。我得到以下异常。 原因:ruleentity

  • 我有一个名为Student实体,它有几个与Student相关的字段,还有一个具有一个任何关系的主题列表。在这里,我需要得到所有的字段,包括主题列表,除了“图像”,因为它使用更多的内存,它需要很长的时间来检索所有行。有没有人可以说,如何创建投影和标准,以检索这个学生对象,没有图像字段单独?有没有像“AliastObeAnneStedResultTransformer”这样的自定义结果转换器?因为在我

  • 问题内容: 默认情况下,我想给我的body元素添加绿色边框。在支持视网膜显示的设备上,我要首先检查尺寸。在ipad上,我想给我的身体一个红色边框,在iphone上,我想给它一个蓝色边框。但是像这样嵌套媒体查询是行不通的: 问题答案: 否。您需要使用运算符并将其写为两个查询。但是,您可以在将编译为CSS的SCSS中执行此操作,但是它将通过展开它们并使用运算符将它们组合在一起。 这是一个普遍的问题,一