【发布时间】:2021-12-17 05:33:14
【问题描述】:
问题
如果要持久化的实体的主键不使用@GeneratedValue,是否可以使用EclipseLink 的batch-writing?
我有@IdClass 使用复合键,并且值是在代码中的实例化过程中分配的。
示例
@Entity
@Table(name = "myentity")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@IdClass(MyIdClass.class)
public class MyEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@Column
private String whatever;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class MyIdClass implements Serializable {
private String foo;
private String bar;
}
上下文
到目前为止,我一直无法激活 EclipseLink 的batch-writing;我只是无法正确配置。
我在网上找到的一些文档似乎提到不将@GeneratedValue 与GenerationType.IDENTITY 一起使用很重要,并且通常建议使用另外两个GenerationType 之一策略。但是,他们似乎并没有特别提到不使用 any 策略也可以让它工作。
【问题讨论】:
-
他们没有提到它,因为它被认为不值得一提——如果你的案例不起作用,批量写入本身对任何人都不起作用。 IDENTITY 生成和排序本身会妨碍批处理,因为它需要从语句中获取值或直接在语句之后立即获取值,这很难确定一个语句何时可以包含 50 个插入,并且如果是,则取决于驱动程序甚至可以做到。任何预先分配了 id 的东西(预分配或只是没有排序)都可以。您遇到了什么问题?
-
@Chris 好吧,首先,我不完全确定如何确保
batch-writing被正确激活。日志中的预期症状是什么?spring.jpa.show-sql=true中的application.properties是否仍会显示单独的INSERT语句,或者我是否会看到包含bind属性的大数组的批处理语句? -
那么就查询而言,顺序是否重要?我有一个需要持久化的具有
@OneToOne关系的实体(它们都需要在数据库中获取upsert)。例如,我目前正在尝试两个选项:1)entityManager#merge。对于每个实体,merge首先发出一个SELECT语句,然后发出 2 个INSERT(一个用于实体,另一个用于 OneToOne 实体):我应该尝试正确订购吗? -
2) 使用数据库中的
@Query+ 触发器批量删除以删除其他关联实体+JPArepository#saveAll。对于第二个选项,我主要想知道saveAll将如何与batch-writing一起工作,考虑到OneToOne:我是否应该再次尝试订购我的INSERTs,以便可能首先保存OneToOnes? -
顺序很重要,是的,但是 JPA 提供程序将在事务中对插入/更新/删除进行排序 - 他们不遵循您称为持久或合并的顺序,除非您调用导致两者之间的冲洗。如果您多次对同一实体类型调用合并,EclipseLink 应该在事务提交或刷新时适当地对插入/更新进行分组。您在日志中看到哪些语句及其顺序?对于选项 2,批量删除会强制刷新上下文中的所有内容。
标签: spring-boot jpa spring-data-jpa spring-data eclipselink