Java 在插入具有嵌入主键的多个实体时优化JPA性能
我天真地实现了一个web服务,它使用Json对象列表,并使用Java 在插入具有嵌入主键的多个实体时优化JPA性能,java,hibernate,spring-boot,jpa,spring-data-jpa,Java,Hibernate,Spring Boot,Jpa,Spring Data Jpa,我天真地实现了一个web服务,它使用Json对象列表,并使用 springframework.data.jpa(jpa&Hibernate)。但是,该解决方案的性能较低,探查器提示我,主要问题在于从Json对象逐个创建实体 下面的代码经过简化,但基本上是:对于传入列表中的每个Json对象,都创建了两个实体:DataEntity和IdentityEntity。前者保存感兴趣的数据,并将后者用作FK,它具有一个时间和一个人的复合PK 我想加快存储过程。我已经通过探查器确定,在插入每个新实体之后,有太
springframework.data.jpa
(jpa&Hibernate)。但是,该解决方案的性能较低,探查器提示我,主要问题在于从Json对象逐个创建实体
下面的代码经过简化,但基本上是:对于传入列表中的每个Json对象,都创建了两个实体:DataEntity和IdentityEntity。前者保存感兴趣的数据,并将后者用作FK,它具有一个时间和一个人的复合PK
我想加快存储过程。我已经通过探查器确定,在插入每个新实体之后,有太多的刷新操作正在进行。由于我需要在给定时间插入数千条记录,因此会导致性能问题。我是否可以在一个事务中进行插入,或者有哪些其他优化方法
数据类(我有许多类似的类):
可嵌入实体:
@Embeddable
public class IdentityEntity implements Serializable {
@NonNull
private Long personId;
@NonNull
private Long datetimeId;
}
JPA存储库:
@Repository
public interface DataRepository extends JpaRepository<DataEntity, IdentityEntity> {}
@存储库
公共接口数据存储库扩展了JpaRepository{}
简化控制器:
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);
}
}
公共类数据控制器{
@自动连线
私有数据存储库;
@自动连线
专用DatetimeRepository DatetimeRepository;
@后映射(“/upload”)
公共无效上载(…列表项){
PersonEntity person=getPerson(…);//足够快
对于(datajsoni:items){//在这里开始事务?
saveNewEntity(i,person.getId());
}
}
私有void saveNewEntity(DataJson,Long personId){
TimeEntity savedDatetime=datetimeRepository.save(新的TimeEntity(json.getDatetime());
IdentityEntity mi=IdentityEntity(personId,savedDatetime.getId());
DataEntity条目=新的DataEntity(mi,json.getData());
dataRepository.save(条目);
}
}
编辑:进一步深入剖析剖析器后,我发现另一个耗时的操作可能是事务管理本身。虽然我还没有实现或配置任何事务行为,但我怀疑Spring引导为Hibernate ORM配置了一些默认设置。我开始认为,在循环的每次迭代中都会创建一个事务,这是第一个性能问题,也是第二个问题的根源,在事务结束时,所有内容都会刷新并写入数据库。是的。
SimpleParepository
中的所有方法都用@Transactional
注释
只需在上载方法中添加一个@Transactional
注释
。。。或
首先创建所有对象,并使用
save(Iterable entities)
方法一次性保存它们。要解释下一票吗?正如您所说,在上传方法上方添加@Transactional是有效的。插入现在大约快了两个数量级,这对我来说已经足够了。谢谢!
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);
}
}