【发布时间】:2017-07-12 09:59:36
【问题描述】:
我正在开发一个使用 JPA (Hibernate) 作为持久层的 Spring Boot 应用程序。
我目前正在实施迁移功能。我们基本上将系统的所有现有实体转储到 XML 文件中。此导出还包括实体的 ID。
我遇到的问题位于另一端,重新导入现有数据。在这一步中,XML 再次转换为 Java 对象并保存到数据库中。
尝试保存实体时,我使用EntityManager 类的merge 方法,该方法有效:一切都已成功保存。
但是,当我打开 Hibernate 的查询日志时,我看到在每个插入查询之前,都会执行一个选择查询以查看具有该 id 的实体是否已经存在。这是因为实体已经有我提供的 id。
我理解这种行为,它实际上是有道理的。但是,我确定 id 将不存在,因此选择对我的情况没有意义。我保存了数千条记录,这意味着对大型表有数千个选择查询,这大大减慢了导入过程。
我的问题:有没有办法关闭“在插入之前检查实体是否存在”?
附加信息:
当我使用 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;
}
}
}
【问题讨论】: