我想出的最好的是
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字段。
但是,另一个问题(在我的情况下实际上是需要这种行为)是您在保存新实体时不能同时更改已引用的现有实体。所有这些更改将被忽略。
重要的提示:
在许多情况下(可能是您的情况),这可能会简单得多。您可以将实体管理器的引用添加到您的服务中:
@PersistenceContextprivate EntityManager entityManager;
在上面的
if(){}块中使用containable = entityManager.merge(containable);
而不是我的代码(如果可行,请试用)。
在我的情况下,类是抽象的,
targetEntity在
@ManyToOne是抽象的,因此也。直接调用entityManager.merge(containable)会导致异常。但是,如果您的课程都是具体的,则应该可以。



