在创建数据时延迟,因为它事先获取了大量数据并且必须保存



我想从先前数据的副本创建数据,并将其与新数据一起保存。

@Entity
@Table(name = "tableA")
@Getter
@Setter
public class TableA {
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
private Long id; 
private String status;

private int revision;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnoreProperties("phMt")
private Field1 field1;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnore
private Field2 field2;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnore
private Field3 field3;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tableA", orphanRemoval = true)
@JsonIgnore
private List<Field4> field4;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnore
private Field5 field5;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tableA", orphanRemoval = true)
@JsonIgnore
private List<Field6> field6;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnore
private Field7 field7;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "tableA")
@JsonIgnore
private Field8 field8;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnore
private Field9 field9;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "tableA")
@PrimaryKeyJoinColumn
@JsonIgnore
private Field10 field10;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tableA", orphanRemoval = true)
@JsonIgnore
private List<Field11> field11;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tableA", orphanRemoval = true)
@JsonIgnore
private List<Field12> field12;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tableA", orphanRemoval = true)
@JsonIgnore
private List<Field13> field13;
}

例如,我想在表A中创建版本为1的数据,我想要的是在创建数据时自动复制先前在表A中的版本0的数据。下面是我创建的一个函数,用于创建与版本0中的数据相同的新数据。

@Transactional
@Override
public void create(String status, String revision) {
TableA tableA = new TableA();
tableA.setStatus(status);
if (status.equals("Revision")) {
tableA.setRevision(revision);
//Clone Field 2
Field2 field2Prev = tableAPrev.getField2();
Field2 field2Next = new Field2();
BeanUtils.copyProperties(field2Prev, field2Next, "id");
field2Next.setTableA(tableANext);
tableANext.setField2(field2Next);
save(tableANext);
//Clone Field 3
Field3 field3Prev = tableAPrev.getField3();
Field3 field3Next = new Field3();
BeanUtils.copyProperties(field3Prev, field3Next, "id");
field3Next.setTableA(tableANext);
tableANext.setField3(field3Next);
save(tableANext);
//Clone Field 4
List<Field4> field4Prev = tableAPrev.getField4();
List<Field4> field4Next = new ArrayList<>();
if (!field4Prev.isEmpty()) {
for (int i = 0; i < field4Prev.size(); i++) {
Field4 field4 = new Field4();
BeanUtils.copyProperties(field4Prev.get(i), field4, "id", "tableA");
field4.setTableA(tableANext);
field4Next.add(field4);
}
field4Repository.saveAll(field4Next);
}
//Clone Field 5
Field5 field5Prev = tableAPrev.getField5();
Field5 field5Next = new Field5();
BeanUtils.copyProperties(field5Prev, field5Next, "id");
field5Next.setTableA(tableANext);
tableANext.setField5(field5Next);
save(tableANext);
//Clone Field 6
List<Field6> field6Prev = tableAPrev.getField6();
List<Field6> field6Next = new ArrayList<>();
if (!field6Prev.isEmpty()) {
for (int i = 0; i < field6Prev.size(); i++) {
Field6 field6 = new Field6();
BeanUtils.copyProperties(field6Prev.get(i), field6, "id", "tableA");
field6.setTableA(tableANext);
field6Next.add(field6);
}
field6Repository.saveAll(field6Next);
}
//Clone Field 7
Field7 field7Prev = tableAPrev.getField7();
Field7 field7Next = new Field7();
BeanUtils.copyProperties(field7Prev, field7Next, "id");
field7Next.setTableA(tableANext);
tableANext.setField7(field7Next);
save(tableANext);
//Clone Field 8
Field8 field8Prev = tableAPrev.getField8();
if (field8Prev != null) {
Field8 field8Next = new Field8();
List<Field8A> field8ANext = new ArrayList<>();
BeanUtils.copyProperties(field8Prev, field8Next, "id", "tableA", "dataChild8A");
field8Next.setTableA(tableANext);
field8Next.setDataChild8A(field8ANext);
field8Repository.save(field8Next);
List<Field8A> field8APrev = field8Prev.getDataChild8A();
if (!field8APrev.isEmpty()) {
for (int i = 0; i < field8APrev.size(); i++) {
Field8A field8A = new Field8A();
BeanUtils.copyProperties(field8APrev, field8A, "id", "field8");
field8A.setField8(field8Next);
field8ANext.add(field8A);
}
field8ARepository.saveAll(field8ANext);
}
}
// etc until Field 13
} 
save(tableA);
}

但是当API被击中时,它没有显示响应并且被延迟。这个过程占用了大量的内存。我想问的是,复制大量数据并完美保存的效率有多高?

我想问的是能够复制大量数据并完美保存它的效率是多少?

正如您所注意到的,这对于大量数据不是很有效。提高性能的第一个方法可能是将其分解为多个事务。由于jpa的缓存行为,它会将所有更改保留在EntityManager中,这可能会导致高内存消耗和糟糕的性能。

但是实际上JPA首先就不是这种工作的正确工具。

我建议通过JDBC模板直接使用SQL。使用INSERT INTO SELECT语句,您应该能够在使用JPA所需的几个百分点的时间内执行相同的操作,因为您不是将所有数据加载到内存中,而是始终将其保存在数据库中。

  • 您应该删除所有中间保存,并将它们替换为only一个在方法的末尾

    像这样:


@Transactional
@Override
public void create(String status, String revision) {
TableA tableA = new TableA();
tableA.setStatus(status);
if (status.equals("Revision")) {
tableA.setRevision(revision);
//Clone Field 2
Field2 field2Prev = tableAPrev.getField2();
Field2 field2Next = new Field2();
BeanUtils.copyProperties(field2Prev, field2Next, "id");
field2Next.setTableA(tableANext);
tableANext.setField2(field2Next);
//Clone Field 3
Field3 field3Prev = tableAPrev.getField3();
Field3 field3Next = new Field3();
BeanUtils.copyProperties(field3Prev, field3Next, "id");
field3Next.setTableA(tableANext);
tableANext.setField3(field3Next);
//Clone Field 4
List<Field4> field4Prev = tableAPrev.getField4();
List<Field4> field4Next = new ArrayList<>();
if (!field4Prev.isEmpty()) {
for (int i = 0; i < field4Prev.size(); i++) {
Field4 field4 = new Field4();
BeanUtils.copyProperties(field4Prev.get(i), field4, "id", "tableA");
field4.setTableA(tableANext);
field4Next.add(field4);
}
}
//Clone Field 5
Field5 field5Prev = tableAPrev.getField5();
Field5 field5Next = new Field5();
BeanUtils.copyProperties(field5Prev, field5Next, "id");
field5Next.setTableA(tableANext);
tableANext.setField5(field5Next);
//Clone Field 6
List<Field6> field6Prev = tableAPrev.getField6();
List<Field6> field6Next = new ArrayList<>();
if (!field6Prev.isEmpty()) {
for (int i = 0; i < field6Prev.size(); i++) {
Field6 field6 = new Field6();
BeanUtils.copyProperties(field6Prev.get(i), field6, "id", "tableA");
field6.setTableA(tableANext);
field6Next.add(field6);
}
}
//Clone Field 7
Field7 field7Prev = tableAPrev.getField7();
Field7 field7Next = new Field7();
BeanUtils.copyProperties(field7Prev, field7Next, "id");
field7Next.setTableA(tableANext);
tableANext.setField7(field7Next);
//Clone Field 8
Field8 field8Prev = tableAPrev.getField8();
if (field8Prev != null) {
Field8 field8Next = new Field8();
List<Field8A> field8ANext = new ArrayList<>();
BeanUtils.copyProperties(field8Prev, field8Next, "id", "tableA", "dataChild8A");
field8Next.setTableA(tableANext);
field8Next.setDataChild8A(field8ANext);
field8Repository.save(field8Next);
List<Field8A> field8APrev = field8Prev.getDataChild8A();
if (!field8APrev.isEmpty()) {
for (int i = 0; i < field8APrev.size(); i++) {
Field8A field8A = new Field8A();
BeanUtils.copyProperties(field8APrev, field8A, "id", "field8");
field8A.setField8(field8Next);
field8ANext.add(field8A);
}
}
}
// etc until Field 13
} 
save(tableANext);
save(tableA);
}