为什么FetchType.Eager在双向映射中阻止org.hibernate.TransientObjectException而CascadeType.ALL不起作用?

奥蒙湖

用.jsp中的数据填充表单支持bean(状态)后,我尝试将其添加到其父实体(员工)中。不幸的是,这导致org.hibernate.TransientObjectException。

在某些线程中建议将CascadeType.ALL添加到@ManyToOne(所有者,Status.java)中没有任何作用,这应该是正确的。但是,除了在CascadeType.ALL之外,在@OneToMany(引用端,Employee.java)上添加fetch = FetchType.EAGER也可以解决此问题(如下代码所示)。

模型“员工”

@Entity
public class Employee {

@OneToMany(mappedBy = "employee", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Status> statusList = new ArrayList<Status>();

public void addStatus(Status status) {
    this.statusList.add(status);
    status.setEmployee(this);
 }
}

模型“状态”

@Entity
public class Status implements Comparable<Status> {

@ManyToOne
@JoinColumn(name = "employee_id")
private Employee employee;

}

控制者

@Controller
public class DashboardController {

@PostMapping("addStatus")
public String addStatus(@Valid @ModelAttribute("newStatus") Status newStatus Principal principal) {

Employee employee = employeeService.getEmployeeByPosition(principal.getName());
        employee.addStatus(newStatus);
        employeeService.updateEmployee(employee);
 }
}

服务

@Service
public class EmployeeService {
public void updateEmployee(Employee employee) {
    employeeRepo.save(employee);
 }
}

我希望@OneToMany端的CascadeType.ALL就足够了。但这导致

HHH000346:托管刷新期间发生错误[org.hibernate.TransientObjectException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:.... model.Status]

另一方面,当我另外使用FetchType.EAGER时,该异常消失了,我无法理解。

麦琪(Maciej Kowalski)

最有可能的:

Employee employee = employeeService.getEmployeeByPosition(principal.getName());

这发生在事务1中

employee.addStatus(newStatus);

在这里,实体已经处于分离状态,并且不急于LAZY加载,从这一点开始将不起作用。

employeeService.updateEmployee(employee);

事务2的此处,您很可能在内部尝试merge,但是该集合尚未被延迟加载。有了EAGER它,合并成功。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章