【问题标题】:Batch insert entity with composite key使用复合键批量插入实体
【发布时间】:2021-01-09 10:02:58
【问题描述】:

拥有这些课程:

public class SomeCompositeKey implements Serializable {
    private Long objectAId;
    private Long objectBId;
    private Long objectCId;
}
//lombok annotations~~
@Entity
@Table(name = "objects_assoc")
@IdClass(SomeCompositeKey.class)
public class ObjectsAssocEntity {

    @Id
    @ManyToOne
    @JoinColumn(name = "object_a_id")
    private ObjectAEntity objectA;

    @Id
    @ManyToOne
    @JoinColumn(name = "object_b_id")
    private ObjectBEntity objectB;

    @Id
    @ManyToOne
    @JoinColumn(name = "object_c_id")
    private ObjectCEntity objectC;

}

我正在使用EntityManager.getReference() 获取ObjectsAssocEntity 成员的引用并尝试使用saveAll 方法一次保存几个实体,并且每次休眠执行选择以检查实体是否存在,然后进行单个插入不存在的情况。

在这种情况下是否有可能使用批量插入?还是我应该尝试这样做,例如使用本机查询?

【问题讨论】:

  • 你用的是什么hibernate方言,hibernate版本?
  • 方言:SQLServer2012方言,休眠版本:5.4.15
  • 批量插入与之前选中的语句无关。您可以通过分析选择后的插入操作来检查它。添加属性 spring.jpa.properties.hibernate.generate_statistics = true 并分析插入日志以确认批处理已执行。关于批量插入之前执行的选择,我面临同样的问题,就像你一样。一旦我有解决方案或理解。我会给你答案!

标签: java hibernate jpa spring-data-jpa


【解决方案1】:

如文档中所述。 spring 默认实现必须知道实体是否是新的。

在唯一主键的情况下:spring更容易判断它是否是新的,因为在插入之前实体id为空。

在复合键的情况下:ID 值总是在持久化之前填充。所以在这种情况下,为了确定实体是否是新的,您可以执行以下方法之一:

  1. 在实体类中使用@Version 属性。对于新对象,版本为空。这样就够了。
  2. 实现 Persistable 接口
  3. 覆盖默认 spring SimpleJpaRepository EntityInformation 并注册为 bean。

建议:@Version 在并发世界中有几个好处。所以用它吧。

Spring docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多