Spring开机。在修改实体时执行 saveAndFlush 会导致未保存的瞬态异常

Spring Boot. Doing a saveAndFlush with modifying an entity results to unsaved trancient exception

我有一个复杂的实体:

public class Task {
   @OneToOne(orphanRemoval=true, mappedBy="parent")
   @Cascade(value = CascadeType.ALL) (org.hibernate.annotations ... package)
   private Executor executor;
...
}

public class Executor {
   @OneToOne
   @JoinColumn
   private Task parent;

   @ManyToOne
   @Cascade(value = CascadeType.ALL)
   private List<Property> propList = new LinkedList<Property>();
}

一般是一个'Task',组成一个'Executor','Executor'填充一些特定的属性。

如果我经常这样做,意思是:

@Service
public class Service {
   @PostConstruct
   private void test() {
      Task task = new Task();
      Executor ex = new Executor();
      List<Property> props = ex.getProperties();
      ... forming and adding some properties
      taskDao.saveAndFlush(task);
   }

一切正常,任务已正确存储。

但是因为这是简化的,我需要在我得到一个任务的那一刻存储它,意思是,在定义之后,并存储它(刷新,不刷新,分成一个单独的方法与事务处理),

@Service
public class Service {
   @PostConstruct
   private void test() {
      Task task = new Task();
      taskDao.saveAndFlush(task); // no change in the exception if I properly move this out to a separate method with @Transactional
      Executor ex = new Executor();
      List<Property> props = ex.getProperties();
      ... forming and adding some properties
      taskDao.saveAndFlush(task);
   }

我得到 "unsaved transaction",它指向第二个 "saveAndFlush"。

这只有在我填写属性后才能实现,这意味着注释掉 "forming properties" 部分,一切正常。

级联是全部(完整列表,保存在 org.hibernate.annotations...),所以我怀疑忘记指定 "Cascade"。

saveAndflush不会将实体变为托管状态,需要使用该方法返回的托管实体。试试这个解决方案:

@PostConstruct
private void test() {
   Task task = new Task();
   task = taskDao.saveAndFlush(task);  // reassign
   Executor ex = new Executor();
   List<Property> props = ex.getProperties();
   ... forming and adding some properties
   taskDao.saveAndFlush(task);
}