gpt4 book ai didi

java - 如何正确保存关联实体?

转载 作者:行者123 更新时间:2023-12-02 10:42:41 25 4
gpt4 key购买 nike

假设我们有以下三个域模型实体:Company , Departament ,和Employee .

@Getter @Setter @NoArgsConstrutor
public class Employee {
private String name;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id", nullable = false, insertable = false, updatable = false)
private Department department;

@JoinColumn(name = "department_id", nullable = false)
private int department_id;
}

@Getter @Setter @NoArgsConstrutor
public class Department {
private String name;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id", nullable = false, insertable = false, updatable = false)
private Company company;

@JoinColumn(name = "company_id", nullable = false)
private int company_id;

@OneToMany(mappedBy = "department")
private List<Employee> employees;
}

@Getter @Setter @NoArgsConstrutor
private class Company {
private String name;

@OneToMany(mappedBy = "company")
private List<Department> departments;
}

对于每个实体,我们有 Repositories延伸JpaRepository , Services ,和Controllers 。在每个 Service我们@Autowire各自Repository ,并且在每个实体中 Controller我们从实体 Service 调用方法.

我的问题如下:我无法保存整个 Company ,因为Departments需要 Company ID,和Employees一个Deparment ID。所以,首先,在我的 CompanyService 中我保存并清除 departments列出,执行 saveAndFlush它将 ID 分配给我的 company 。我将收到的 ID 分配给每个 company_id在先前保存的每个实体中departments列表,然后将该列表附加回 company然后再做一次saveAndFlush ,我再为 employee 执行此操作一次列表。

@RestController
public class CompanyController {
@Autowire
private CompanyService companyService;

@PostMapping("/companies")
public Company createCompany(@RequestBody Company newCompany) {
return companyService.createCompany(newCompany);
}
}

@Service
public class CompanyService {
@Autowire
private CompanyRepository companyRepository;

public Company createCompany(Company company) {
List<Department> departments = new ArrayList<>(company.getDepartments());
company.getDepartments().clear();

companyRepository.saveAndFlush(company);

int company_id = company.getId();

departments.forEach (department ->
department.setCompany_id(company_id);
);

//here I save a copy of the previously saved departments, because I still need the employees
company.getDepartments().addAll(departments.stream().map(department -> department.clone(department)).collect(Collectors.toList()));
company.getDepartments().forEach(department -> department.getEmployees().clear());

companyRepository.saveAndFlush(company);

//here I assign each employee it's corresponding department ID
for (int i = 0; i < company.getDepartments().size(); i++) {
Department departmentInSavedCompany = company.getDepartments().get(i);
Department departmentWhichStillHasEmployees = departments.get(i);

departmentWhichStillHasEmployees.setId(departmentInSavedCompany.getId());
departmentWhichStillHasEmployees.getEmployees().forEach(employee -> employee.setDepartment_id(departmentInSavedCompany.getId()));
}

company.getDepartments.clear();
company.getDepartments.addAll(departments);

return companyRepository.saveAndFlush(company);
}
}

@Repository
public interface CompanyRepository extends JpaRepository<Company, Integer> {

}

我目前不喜欢这个实现,也不觉得它很好。对于这种情况,哪种方法是正确的?

最佳答案

使用 JPA 时,不要使用 ID,而是使用对象引用。

就您而言,这意味着删除重复引用的 id 属性。

为了获取 ID 的正确实体,请使用 JpaRepository.getOne 。如果实体已经在一级缓存中,它将返回实体,或者只是包装 ID 的代理,因此它不会访问数据库。

这允许您组装对象图并将其持久化,从不引用其他实体的实体开始。

如果您认为实体是同一个聚合的一部分,您也可以考虑配置级联,即它们应该一起加载和持久化。

关于java - 如何正确保存关联实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52815598/

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