我在Task和TaskError之间有一个简单的OneToMany关系。
任务映射TaskErrors:
@OneToMany(cascade = CascadeType.ALL, mappedBy = "task", orphanRemoval = true)
private List<TaskError> taskErrorCollection;
删除任务时应删除TaskErrors,因此删除orphanRemoval。
TaskError连接到任务:
@JoinColumn(name = "task_id", referencedColumnName = "id")
@ManyToOne(optional = false, cascade = CascadeType.ALL)
private Task task;
当我使用以下代码添加TaskError时,任务中的TaskErrors列表不会更新:
TaskError taskError;
// set all taskErrors vars
taskErrorDAO.create(taskError);
因此,数据库包含TaskError的行,而未填充Task中的TaskErrors列表。显然,当我删除任务时,它会出错: MySQLIntegrityConstraintViolationException:无法删除或更新父行
我个人是否需要在Task中填充TaskError列表?有没有办法自动填充此列表?在taskErrorDAO.create(taskError)之后的em.flush没有帮助。
答案 0 :(得分:4)
开发人员负责实体关系的内存表示。所以 - 是的,您需要填充TaskError
Task
列表中的TaskError
个实例。
您可以尝试清理PersistenceContext
的{{1}}缓存并直接从数据库中重新获取,如下所示:
Task
或
em.refresh(task);
无论哪种方式,您的JPA提供程序都应清除实体的内存中表示,点击数据库(正如您所说,正确插入行)以获取它并正确加载列表。但是,从长远来看,我不会这样做,而是相应地更新我的对象引用
如果您拒绝更新实体的内存关系,则不能使用em.clear();
task = em.find(Task.class, yourTaskId);
的缓存功能。为了获得正确的数据,每次要在分配任何新PersistenceContext
之后使用/获取Task
实体时,您都需要访问数据库。
还有一件事 - 为什么TaskError
中有Cascade.ALL
?如果删除TaskError
,是否要删除Task
个实例?
您还可以查看this resource以获取更多信息。