Java spring boot项目中的JPA“批插入”速度非常慢

Java spring boot项目中的JPA“批插入”速度非常慢,java,jpa,spring-boot,batch-insert,Java,Jpa,Spring Boot,Batch Insert,嘿,我正试图插入800行@oneToMany关系,但它们似乎真的很慢。我不太明白为什么,因为我读过一些指南,说它应该相当快。 因此,我希望善良的灵魂能告诉我是否有什么我误解了,并能帮助我提高插入的性能 存储库: “子”实体类: 当前运行时: 插入796行脚注和900个描述周期的时间超过4分钟276642ms除非与AspectJ发生严重争执,否则私有方法通常不是@Transactional。也许你关于它应该有多快的假设是基于一个关于所涉及的网络往返次数的错误前提?。你对提交的评论也暗示了很多,但我

嘿,我正试图插入800行@oneToMany关系,但它们似乎真的很慢。我不太明白为什么,因为我读过一些指南,说它应该相当快。 因此,我希望善良的灵魂能告诉我是否有什么我误解了,并能帮助我提高插入的性能

存储库:

“子”实体类:

当前运行时:
插入796行脚注和900个描述周期的时间超过4分钟276642ms

除非与AspectJ发生严重争执,否则私有方法通常不是@Transactional。也许你关于它应该有多快的假设是基于一个关于所涉及的网络往返次数的错误前提?。你对提交的评论也暗示了很多,但我不确定我对这些假设了解得是否足够。我只想尽快保存这两个对象,它们相互引用。我尝试删除@Transactional,现在只剩下1/4的时间了。你能解释一下原因吗?你的代码的问题是它在一个事务中运行。这意味着一级缓存已满。保存完成后,将检查一级缓存中的所有对象是否脏。现在,10个对象没有问题,但每增加一个对象,就加起来。在循环中,您应该做的是在达到定义的批处理大小后添加刷新和清除。这将清除缓存并保持性能。但仍然保持单个发送。多个发送的问题是,当一个发送失败时,其他发送仍保持提交状态。事实上,我确实尝试过使用batchsize 20,并刷新和清除。这似乎没有什么不同。。但是当你像我上面所说的那样拥有它时,类之间就有了关系。如果我在每个表/实体上将@batchsize设置为20,那么您应该如何计算@batchsize,我什么时候才能清除和刷新?总共20个?或者他们中的任何一个先达到20岁?
@Repository
public interface FootnoteRepository extends CrudRepository<FootnotesEntity, Long> {

    @Query("FROM FOOTNOTES WHERE number =?1 AND FOOTNOTE_TYPE=?2 order by DATE_START desc,id asc")
    public List<FootnotesEntity> findFootnoteByNumberAndType(Long number, String transportNumber, Pageable pageable);
}
@Autowired
private EntityRepository entityRepository;

@Autowired
private FootnoteRepository footnoteRepository;
/**
 * Handles the JPA Interface
 * 
 * @param
 * @return the success of the operation
 */
@Transactional
private boolean insertUpdateFootnoteEntities(List<FootnotesEntity> footnotes) {
    boolean success = true;
    System.out.println("footnotes: " + footnotes.size());
    long start = System.currentTimeMillis();
    try {
        // TODO fix below: (does not "commit" the deletion")
        // footnoteRepository.deleteAll();

        // TODO speed optimize
        footnoteRepository.save(footnotes);

    } catch (Exception e) {
        e.printStackTrace();
        success = false;
    }
    long end = System.currentTimeMillis();
    System.out.println("time: " + (end - start));
    return success;
}
@Table(indexes = { @Index(columnList = "FOOTNOTE_NUMBER,FOOTNOTE_TYPE") }, uniqueConstraints = @UniqueConstraint(columnNames = {
        "FOOTNOTE_NUMBER", "FOOTNOTE_TYPE", "DATE_START" }))
@Entity(name = "FOOTNOTES")
@EqualsAndHashCode(callSuper = false)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class FootnotesEntity extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "FOOTNOTES_ID")
    protected Long id;

    @Column(name = "FOOTNOTE_NUMBER")
    protected Long number;

    @Column(name = "FOOTNOTE_TYPE")
    protected String footnoteType;

    @Column(name = "APPLICATION_CODE")
    private String applicationCode;

    @Column(name = "shortDescription", length = 2000)
    private String shortDescription;

    @Column(name = "DATE_START")
    private Date startDate;

    @Column(name = "DATE_END")
    private Date endDate;

    @OneToMany(mappedBy = "footnote", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("startDate desc")
    protected List<DescriptionPeriodsEntity> descriptionPeriods;
}
@Entity(name = "DESCRIPTION_PERIODS")
@EqualsAndHashCode(callSuper = false)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DescriptionPeriodsEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "DESCRIPTION_PERIODS_ID")
    private Long id;

    @Column(name = "DATE_START")
    private Date startDate;

    @Column(name = "DATE_END")
    private Date endDate;

    @Column(name = "DESCRIPTION", length = 5000)
    protected String description;

    @Column(name = "LANGUAGES_ID")
    protected String languagesId;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn(name = "FOOTNOTES_ID")
    protected FootnotesEntity footnote;

}