3 回答

TA贡献1893条经验 获得超10个赞
请参阅有关失败原因的代码注释:
@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
@Transactional
public class OrganizationRepositoryTests {
@Autowired
private OrganizationRepository organizationRepository;
@Autowired
private DepartmentRepository departmentRepository;
@PersistenceContext
private Entitymanager em;
@Test
public void testDeleteOrganization() {
Organization organization =
organizationRepository.findByName(organizationName).get();
Department d1 = new Department();
d1.setName("d1");
d1.setOrganization(organization);
Department d2 = new Department();
d2.setName("d2");
d2.setOrganization(organization);
departmentRepository.save(d1);
departmentRepository.save(d2);
// this fails because there is no trip to the database as Organization
// (the one loaded in the first line)
// already exists in the current entityManager - and you have not
// updated its list of departments.
// uncommenting the following line will trigger a reload and prove
// this to be the case: however it is not a fix for the issue.
// em.clear();
assertEquals(2,
organizationRepository.getOne(
organization.getId()).getDepartments().size());
//similary this will execute without error with the em.clear()
//statement uncommented
//however without that Hibernate knows nothing about the cascacding
//delete as there are no departments
//associated with organisation as you have not added them to the list.
organizationRepository.deleteById(organization.getId());
assertFalse(organizationRepository.findByName(organizationName).isPresent());
assertEquals(0, departmentRepository.findAll().size());
}
}
正确的解决方法是通过封装添加/删除/设置操作并防止直接访问集合来确保始终正确维护内存模型。例如
public class Department(){
public void setOrganisation(Organisation organisation){
this.organisation = organisation;
if(! organisation.getDepartments().contains(department)){
organisation.addDepartment(department);
}
}
}
public class Organisation(){
public List<Department> getDepartments(){
return Collections.unmodifiableList(departments);
}
public void addDepartment(Department departmenmt){
departments.add(department);
if(department.getOrganisation() != this){
department.setOrganisation(this);
}
}
}

TA贡献1818条经验 获得超7个赞
试试这个代码,
@OneToMany( fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "organisation_id", referencedColumnName = "id")
private List<Department> departments;
@ManyToOne(fetch = FetchType.EAGER,ascade = CascadeType.REFRESH,mappedBy = "departments")
private Organization organization;
如果有任何问题通知

TA贡献1780条经验 获得超4个赞
您可以尝试添加以限制级联删除操作仅从组织到部门:
@OneToMany(mappedBy = "organization", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE, orphanRemoval = true) private List<Department> departments;
请注意,如果您对部门实体有依赖/外键约束,那么您还需要将删除操作级联到这些依赖实体。
您可以阅读本指南,它很好地解释了级联操作: https ://vladmihalcea.com/a-beginners-guide-to-jpa-and-hibernate-cascade-types/
添加回答
举报