我有与这3个实体映射的多种关系:
@Entity
public class ApplicatifDo {
.....
@OneToMany(cascade = CascadeType.ALL, mappedBy = "applicatifDo", fetch = FetchType.EAGER, orphanRemoval = true)
private Set<ApplicatifTerminalDo> applicatifTerminalSet;
.....
}
@Entity
public class ApplicatifTerminalDo {
......
@ManyToOne
@JoinColumn(name = "idApplicatif", nullable = false)
private ApplicatifDo applicatifDo;
@ManyToOne
@JoinColumn(name = "idTerminal", nullable = false)
private TerminalDo terminalDo;
@Column
private String remarques;
......
}
@Entity
public class TerminalDo {
......
@OneToMany(cascade = CascadeType.ALL, mappedBy = "terminalDo", fetch = FetchType.EAGER, orphanRemoval = true)
private Set<ApplicatifTerminalDo> applicatifTerminalSet;
......
}
我尝试从两个实体ApplicatifDo和TerminalDo对连接表ApplicatifTerminalDo进行许多级联测试。当我在Set中创建或更新ApplicatifTerminalDo时,级联效果很好,但是当涉及到orphanRemoval或删除它不起作用时
首先:
对于删除,我收到错误:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`softtwo`.`applicatifterminal`, CONSTRAINT `FK_295tcnx7wjuvv5se1g3vldxxn` FOREIGN KEY (`idApplicatif`) REFERENCES `applicatif` (`id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
.....
我希望当我删除ApplicationatifDo或TerminalDo实体时,ApplicatifTerminal连接表中与它们相关的所有行也会被删除。
第二名:
对于orphanRemoval,当我从ApplicatifDo实体的ApplicatifTerminalSet中删除一个元素并执行合并,然后测试它我通过他的父实体的Id进行查找新的完全相同的实体和计数集合中的元素数量我得到的好数字(biginning的数字少一个)。但是在我的数据库中,我仍然拥有我的Set的所有数据。
代码:
//My applicatifDo1 has 4 elements in the ApplicatifTerminalSet here
Assert.assertEquals(applicatifDo1.getApplicatifTerminalSet().size(), 4);
Iterator<ApplicatifTerminalDo> iterator = applicatifDo1
.getApplicatifTerminalSet().iterator();
boolean first = true;
while (iterator.hasNext()) {
ApplicatifTerminalDo element = iterator.next();
if (!first) {
element.setRemarques("remarques updated");
} else {
iterator.remove();
first = false;
}
}
// updateApplicatifDo do just a merge
applicatifDao.updateApplicatifDo(applicatifDo1.getId(), applicatifDo1);
ApplicatifDo applicatifDo = applicatifDao
.findApplicatifDo(applicatifDo1.getId());
Assert.assertEquals(applicatifDo.getApplicatifTerminalSet().size(), 3);
当我这样做时,setRemarques()的更新效果很好。 当我这样做时,我在控制台中没有错误。然后删除似乎工作,因为我通过他的ID检索相同的对象它仍然说我有3个元素,然后第四个已被删除:但是,当我在phpmyadmin中查看我的appplicationterminal表中的4个元素/关系时还在那里。 如果我稍后再做一次TestNg,那么这次只需要通过他的Id检索我的应用程序,它就会获得四个元素。 然后这里出现了一个很大的完整性问题,而且我仍然总是急切地使用。知道为什么会出现这样的问题?我怎么能做我的级联工作?
第三:
更全局的是,我在其他两个实体上有另一个级联+ orphanRemoval规则并且运行良好,但这些级联的实体目标与其他实体没有其他关系。 显然,当对具有其他关系的实体进行级联时,存在特定的规则(或可能是限制)。 请您了解解释此类映射的最佳实践的教程/规则吗?
提前致谢。我坚持了这么久。