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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了春季启动。通过修改实体来执行saveAndFlush会导致未保存的特殊异常相关的知识,希望对你有一定的参考价值。

我有一个复杂的实体:

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

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

这只有在填写属性时才能实现,这意味着注释掉“形成属性”部分,一切运行良好。

级联是ALL(完整列表,保存在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);

以上是关于春季启动。通过修改实体来执行saveAndFlush会导致未保存的特殊异常的主要内容,如果未能解决你的问题,请参考以下文章

春季启动补丁

春季启动数据休息中的日期问题

何时为春季启动执行指定多个配置文件

春季启动 DispatcherServlet

如何在春季启动时在浏览器中查看默认网址?

春季启动批处理到具有多个作业的春季云任务