批量插入现有数据:防止 JPA 在每次插入之前进行选择

2023-12-20

我正在开发一个 Spring Boot 应用程序,该应用程序使用 JPA (Hibernate) 作为持久层。

我目前正在实现迁移功能。我们基本上将系统的所有现有实体转储到 XML 文件中。此导出还包括实体的 ID。

我遇到的问题位于另一侧,重新导入现有数据。在此步骤中,XML 再次转换为 Java 对象并保存到数据库中。

当尝试保存实体时,我正在使用merge的方法EntityManager类,有效:一切都已成功保存。

然而,当我打开 Hibernate 的查询日志记录时,我看到在每个插入查询之前,都会执行一个选择查询来查看具有该 id 的实体是否已存在。这是因为该实体已经有我提供的 ID。

我理解这种行为,而且它实际上是有道理的。但我确信 ids 不会存在,因此选择对我的情况没有意义。我保存了数千条记录,这意味着大型表上有数千条选择查询,这大大减慢了导入过程。

我的问题:有没有办法关闭“在插入之前检查实体是否存在”?


附加信息:

当我使用entityManager.persist()我没有合并,而是得到了这个异常:

org.hibernate.PersistentObjectException:分离的实体传递给 坚持

为了能够使用提供的/提供的 id,我使用这个 id 生成器:

@Id
@GeneratedValue(generator = "use-id-or-generate")
@GenericGenerator(name = "use-id-or-generate", strategy = "be.stackoverflowexample.core.domain.UseIdOrGenerate")
@JsonIgnore
private String id;

发电机本身:

public class UseIdOrGenerate extends UUIDGenerator {

  private String entityName;

  @Override
  public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
      entityName = params.getProperty(ENTITY_NAME);
      super.configure(type, params, serviceRegistry);
  }

  @Override
  public Serializable generate(SessionImplementor session, Object object) 
  {
        Serializable id = session
            .getEntityPersister(entityName, object)
            .getIdentifier(object, session);

      if (id == null) {
        return super.generate(session, object);
      } else {
        return id;
      }
  }
}

如果您确定永远不会更新数据库上的任何现有条目,并且所有实体都应始终是新插入的,那么我会选择persist操作而不是merge.

每次更新

在这种情况下(id 字段设置为自动生成),唯一的方法是从 id 字段中删除生成注释并将配置保留为:

@Id
@JsonIgnore
private String id;

所以基本上将 id 设置为始终手动分配。然后,即使 id 存在,持久性提供者也会将您的实体视为瞬态实体。这意味着persist会起作用并且不会生成额外的选择。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

批量插入现有数据:防止 JPA 在每次插入之前进行选择 的相关文章

随机推荐