春季启动。通过修改实体执行saveAndFlush导致未保存的过时异常

时间:2019-04-17 14:37:40

标签: java spring hibernate spring-boot spring-data-jpa

我有一个复杂的实体:

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>();
}

通常,它是一个“任务”,形成一个“执行程序”,并且“执行程序”中填充了一些特定的属性。

如果我定期进行此操作,则意味着:

@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);
   }

一切都很好,并且可以正确存储任务。

但是,由于这是简化的操作,因此我需要在定义之后立即存储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);
   }

我得到了“未保存的交易”,它指向第二个“ saveAndFlush”。

仅当我填写属性时,这才可以实现,这意味着注释掉“成型属性”部分,一切运行良好。

级联是ALL(完整列表,保存在org.hibernate.annotations ...中),因此我对忘记指定“级联”感到怀疑。

1 个答案:

答案 0 :(得分:1)

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);
}