问题基本上与下面的问题相同:
JPA级联仍然存在,对分离实体的引用将引发PersistentObjectException。为什么?
我正在创建一个引用现有的分离实体的新实体。现在,当我将此实体保存在spring数据存储库中时,会引发异常:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist
如果我们查看Spring数据JPA的源代码中的save()方法,则会看到:
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
如果我们看一下isNew() AbstractEntityInformation
public boolean isNew(T entity) {
return getId(entity) == null;
}
因此,基本上,如果我保存()一个新实体(id == null)
,spring数据将始终调用persist,因此此方案将始终失败。
将新项目添加到集合时,这似乎是一个非常典型的用例。
我该如何解决?
编辑1:
注意:
此问题与如何保存在Spring
JPA中引用现有实体的新实体
没有直接关系?。详细地说,假设您收到通过http创建新实体的请求。然后,您从请求中提取信息,并创建您的实体和现有的引用实体。因此,它们将始终处于分离状态。
我想出的最好的是
public final T save(T containable) {
// if entity containable.getCompound already exists, it
// must first be reattached to the entity manager or else
// an exception will occur (issue in Spring Data JPA ->
// save() method internal calls persists instead of merge)
if (containable.getId() == null
&& containable.getCompound().getId() != null){
Compound compound = getCompoundService()
.getById(containable.getCompound().getId());
containable.setCompound(compound);
}
containable = getRepository().save(containable);
return containable;
}
我们检查是否处于有问题的情况,如果是,只需按ID从数据库重新加载现有实体,然后将新实体的字段设置为该新加载的实例。然后将其附加。
这要求新实体的服务拥有对被引用实体的服务的引用。这应该不是问题,因为无论如何您都在使用spring,因此可以将服务添加为新@Autowired
字段。
但是,另一个问题(在我的情况下实际上是需要这种行为)是您在保存新实体时不能同时更改已引用的现有实体。所有这些更改将被忽略。
重要的提示:
在许多情况下(可能是您的情况),这可能会简单得多。您可以将实体管理器的引用添加到您的服务中:
@PersistenceContext
private EntityManager entityManager;
在上面的if(){}
块中使用
containable = entityManager.merge(containable);
而不是我的代码(如果可行,请试用)。
在我的情况下,类是抽象的,targetEntity
在@ManyToOne
是抽象的,因此也。直接调用entityManager.merge(containable)会导致异常。但是,如果您的课程都是具体的,则应该可以。
我有2个实体(我删除了无用的字段): 而且 这似乎符合我的情况(也是我当前的实现),但它不起作用。 我得到以下错误消息: 来自MySQL: 临时解决方案是从存储库中检索所有相应的权限(按permissionName搜索)。那么保存效果很好。逻辑上是正确的,但我希望有一个更简单的程序...
我有两个实体 实体1 实体2 我对Jpa不是很熟悉,所以如果您需要对我的问题进行任何澄清,或者您需要任何更多的信息,请告诉我。
我尝试读取ExcelFiles并将数据保存在postgres数据库中。在某些文件中,我会得到以下错误消息: null 在大多数已爬网的数据中,什么都没有发生。当我尝试保存semster对象时会出现错误。Excel文件的结构如下:标题、模块号、语言、学期号
Thread[hz._hzinstance_1_dev.partition-operation.thread-3,5,_hzinstance_1_dev]无法进行远程调用:com.hazelcast.collection.impl.collection.operations.CollectionAddOperation{serviceName='hz:impl:setService',identi
问题内容: 我将SpringJPARepository与hibernate一起使用,并且对实体更新有一个问题。我通过传递单个实体来调用jparepository.save(entity),但在跟踪日志中,我也可以看到针对数据库中其他行发出的更新语句。在调用save之前,我有一个findAll并且某些实体的值正在更改。但是我只传递了一个要保存的实体,但是仍然保存了所有更新的实体。您能提供有关此信息吗