我发现了一些问题,我想知道我是否只是想丢失一些东西,或者这是一个真正的问题,可以通过某种方式解决。
项目已配置批处理:
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
,它正在工作。但是我们有一些实体没有生成ID,例如:
@Entity
public class SomeEntity {
@Id
private String id;
//...
}
并说,我们从用户那里获得了1,000,000,并且希望将其插入,或者更糟糕的是使用现有的UPDATE。因此,我们将使用org.springframework.data.repository.CrudRepository#saveAll
。将会发生什么:
save
save
都会呼叫entityInformation.isNew(entity)
,如果持续发出,则每次呼叫都会得到响应false
。 save
将为每个实体调用合并。 merge
调用首先被选择,而那些不能被批量处理,因此将产生N + 1个问题。将有100万个选择,然后是正确的批处理插入。现在如何解决它?
现在考虑更新的可能性:如果我知道我正在使用这样的实体(具有未生成的ID),则可以覆盖发出简单saveAll
的{{1}}方法,以找出哪个实体 实际上存在于系统中,对那些实体进行批量合并(即,使用select id from ... where id in ()
将所有实体引入持久性上下文,然后在它们上调用findAllById
-一次),然后批处理与那些没有的批处理(简单的em.merge
循环)一起保存。
但是我不是JPA专家,所以有以下问题:
em.persist
井即使对于具有非生成IDs IIUC的实体也应该是固定的,以便在插入/更新混合在一起时实际发生批处理。可以说我不想有两个根,一个根用于生成的实体,第二个用于非生成ID的实体。有没有一种方法,如何找出实体是否使用生成的ID?可能可以简化查找方法,如果ID字段分配了生成器?谢谢!