gpt4 book ai didi

java - 批量插入现有数据 : Preventing JPA to do a select before every insert

转载 作者:行者123 更新时间:2023-11-30 07:53:12 25 4
gpt4 key购买 nike

我正在开发一个将 JPA (Hibernate) 用于持久层的 Spring Boot 应用程序。

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

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

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

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

我理解这种行为,它实际上是有道理的。但是我确定 ID 将不存在,因此选择对我的情况没有意义。我正在保存数以千计的记录,这意味着对大型表进行数以千计的选择查询,这大大减慢了导入过程。

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


附加信息:

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

org.hibernate.PersistentObjectException: detached entity passed to persist

为了能够使用提供/提供的 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 操作而不是 合并

每次更新

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

@Id
@JsonIgnore
private String id;

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

关于java - 批量插入现有数据 : Preventing JPA to do a select before every insert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45054477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com