gpt4 book ai didi

java - 一对多关系支持读取和删除,但不支持插入

转载 作者:行者123 更新时间:2023-12-02 10:20:59 26 4
gpt4 key购买 nike

我想扩展 earlier post 中提到的要求以支持删除。我们有两个数据模型对象 - 组织和部门共享一对多关系。通过下面的映射,我可以从组织对象中读取部门列表。我没有添加cascade ALL属性来限制创建组织时添加部门。

我应该如何修改@OneToMany注释(可能还有@ManyToOne)来限制部门的插入,但级联删除操作,以便在删除组织对象时删除所有关联的部门?

@Entity
@Table(name="ORGANIZATIONS")
public class Organization{

@Id
@GeneratedValue
Private long id;

@Column(unique=true)
Private String name;

@OneToMany(mappedBy = "organization", fetch = FetchType.EAGER)
private List<Department> departments;


}

@Entity
@Table(name="DEPARTMENTS")
Public class Department{

@Id
@GeneratedValue
Private long id;

@Column(unique=true)
Private String name;


@ManyToOne(fetch = FetchType.EAGER)
private Organization organization;

}

删除组织的代码只有一行

organizationRepository.deleteById(orgId);

验证这一点的测试用例如下

@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
@Transactional
public class OrganizationRepositoryTests {

@Autowired
private OrganizationRepository organizationRepository;

@Autowired
private DepartmentRepository departmentRepository;



@Test
public void testDeleteOrganization() {
final organization organization = organizationRepository.findByName(organizationName).get(); //precondition

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

// assertEquals(2, organizationRepository.getOne(organization.getId()).getDepartments().size()); //this assert is failing. For some reason organizations does not have a list of departments

organizationRepository.deleteById(organization.getId());

assertFalse(organizationRepository.findByName(organizationName).isPresent());
assertEquals(0, departmentRepository.findAll().size()); //no departments should be found

}

}

最佳答案

查看有关失败原因的代码注释:

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

关于java - 一对多关系支持读取和删除,但不支持插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54342123/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com