在插入带有嵌入式主键的实体时优化JPA性能

我天真地实现了一个Web服务,该服务使用Json对象的列表并将它们存储在SQL数据库中,使用 springframework.data.jpa(JPA和休眠)。但是,该解决方案的性能很差,分析器提示我主要问题在于从Json对象一个接一个地创建实体。

下面的代码已简化,但基本上是这样的:对于传入列表中的每个Json对象,都会创建两个实体:DataEntity和IdentityEntity。前者保存感兴趣的数据,并将后者用作FK,后者具有时间和人的复合PK。

我想加快存储过程。我已经通过分析器确定,在插入每个新实体之后,正在执行太多的 flush 操作。由于我需要在给定的时间插入数千条记录,因此会导致性能问题。也许我可以在一个事务中进行插入,或者可以通过其他方式对其进行优化吗?

数据类(我有很多类似的类):

@Entity
public class DataEntity {
    @EmbeddedId
    private IdentityEntity identity;
    private Double data;
}

可嵌入的实体:

@Embeddable
public class IdentityEntity implements Serializable {
    @NonNull
    private Long personId;
    @NonNull
    private Long datetimeId;
}

JPA存储库:

@Repository
public interface DataRepository extends JpaRepository<DataEntity,IdentityEntity> {}

简化的控制器:

public class DataController{
    @Autowired
    private DataRepository dataRepository;
    @Autowired
    private DatetimeRepository datetimeRepository;

    @PostMapping("/upload")
    public void upload(...List<DataJson> items) {
        PersonEntity person = getPerson(...);          // fast enough
        for (DataJson i : items) {                 // begin transaction here?
            saveNewEntity(i,person.getId());
        }
    }

    private void saveNewEntity(DataJson json,Long personId) {
        TimeEntity savedDatetime = datetimeRepository.save(new TimeEntity(json.getDatetime()));
        IdentityEntity mi = IdentityEntity(personId,savedDatetime.getId());

        DataEntity entry = new DataEntity(mi,json.getData());
        dataRepository.save(entry);
    }
}

编辑:在进一步分析探查器之后,我发现另一个耗时的操作可能是事务管理本身。尽管我还没有实现或配置任何事务行为,但是我怀疑Spring Boot为Hibernate ORM配置了默认值。我开始认为现在正在循环的每个迭代中创建事务,这是第一个性能问题,并且还导致了第二个问题,在事务结束时,所有内容都被刷新并写入到数据库中。>

zudy2 回答:在插入带有嵌入式主键的实体时优化JPA性能

是的。 SimpleJpaRepository中的所有方法都用@Transactional注释。

只需在您的上传方法中添加一个@Transactional注释。

...或

首先创建所有对象,然后使用save(Iterable<S> entities)方法一次性保存它们。

本文链接:https://www.f2er.com/3159311.html

大家都在问