gpt4 book ai didi

java - 更新@OneToMany 关系(Spring Boot、Spring Data)

转载 作者:行者123 更新时间:2023-12-05 03:35:48 24 4
gpt4 key购买 nike

我有一个OneToMany 关系(两个表是双向的)。当我保存医生的专业时,它确实有效,但当我删除任何专业并更新医生时,它不起作用。

医生

@Entity
@Table(name = "doctors")
public class Doctor implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer doctorId;

@Column(length = 20)
private String doctorName;

@Column(length = 9)
private String doctorPhoneNo;

@Column(length = 30)
private String doctorEmailAddress;

private String doctorProfileImage;

@Enumerated(EnumType.STRING)
private Status status;

@Column(length = 6)
private String doctorCmp;

@OneToMany(mappedBy = "doctor", cascade = CascadeType.ALL)
// @JsonIgnore
private Set<DoctorSpecialties> doctorSpecialties;

public Doctor() {
this.doctorSpecialties = new HashSet<>();
}

public Doctor(Integer id){
this();
this.doctorId = id;
}

// getters y setters
}

专业

@Entity
@Table(name = "specialties")
public class Specialty implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer specialtyId;

private String specialtyName;

@OneToMany(mappedBy = "specialty")
@JsonIgnore
private Set<DoctorSpecialties> doctorSpecialties;

public Specialty() {
}

public Specialty(Integer id) {
this.specialtyId = id;
}

// getters and setters
}

专科医师

@Entity
@Table(name = "doctor_specialties")
public class DoctorSpecialties implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "doctor_id")
private Doctor doctor;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "specialty_id")
private Specialty specialty;

@OneToMany
@JoinColumn(name = "doctor_specialties_id")
private Set<Appointment> appointments;

@OneToMany
@JoinColumn(name = "doctor_specialties_id")
private Set<DoctorSchedule> schedules;

public DoctorSpecialties(){

}

public DoctorSpecialties(Specialty specialty, Doctor doctor){
this.specialty = specialty;
this.doctor = doctor;
}
getters / setters
}

Controller

@PostMapping(value = "/saveSpecialties/{id}")
public String saveDoctorSpecialties(@RequestParam(required = false) String[] specialtiesId,
@PathVariable Integer id, RedirectAttributes message) {

if (id != null && id > 0) {
Doctor doctor = doctorService.findOne(id);

if (doctor != null) {

// It does not work
doctor.getDoctorSpecialties().forEach(ds -> doctorSpecialtiesService.delete(ds.getId()));

doctor.getDoctorSpecialties().clear();

if (specialtiesId != null) {
for (String specialtyId : specialtiesId) {
DoctorSpecialties ds = new DoctorSpecialties();
ds.setSpecialty(new Specialty(Integer.parseInt(specialtyId)));

ds.setDoctor(doctor);

doctor.getDoctorSpecialties()
.add(ds);
}

}
doctorService.update(doctor);
message.addFlashAttribute("success", "Specialties successfully saved.");
return "redirect:/doctors/profile/{id}/specialties";
}
}
// specialtiesId = new String[]{};
message.addFlashAttribute("error", "Doctor doesn't exists");
return "redirect:/doctors/list";
}

控制台:

2021-10-30 21:19:13.330 DEBUG 44504 --- [nio-8080-exec-7] org.hibernate.SQL : select doctor0_.doctor_id as doctor_i1_3_0_, doctor0_.doctor_cmp as doctor_c2_3_0_, doctor0_.doctor_email_address as doctor_e3_3_0_, doctor0_.doctor_name as doctor_n4_3_0_, doctor0_.doctor_phone_no as doctor_p5_3_0_, doctor0_.doctor_profile_image as doctor_p6_3_0_, doctor0_.status as status7_3_0_ from doctors doctor0_ where doctor0_.doctor_id=?2021-10-30 21:19:13.339 DEBUG 44504 --- [nio-8080-exec-7] org.hibernate.SQL : select doctorspec0_.doctor_id as doctor_i2_2_0_, doctorspec0_.id as id1_2_0_, doctorspec0_.id as id1_2_1_, doctorspec0_.doctor_id as doctor_i2_2_1_, doctorspec0_.specialty_id as specialt3_2_1_ from doctor_specialties doctorspec0_ where doctorspec0_.doctor_id=?2021-10-30 21:19:13.401 DEBUG 44504 --- [nio-8080-exec-8] org.hibernate.SQL : select doctor0_.doctor_id as doctor_i1_3_0_, doctor0_.doctor_cmp as doctor_c2_3_0_, doctor0_.doctor_email_address as doctor_e3_3_0_, doctor0_.doctor_name as doctor_n4_3_0_, doctor0_.doctor_phone_no as doctor_p5_3_0_, doctor0_.doctor_profile_image as doctor_p6_3_0_, doctor0_.status as status7_3_0_ from doctors doctor0_ where doctor0_.doctor_id=?2021-10-30 21:19:13.404 DEBUG 44504 --- [nio-8080-exec-8] org.hibernate.SQL : select specialty0_.specialty_id as specialt1_7_0_, doctorspec1_.id as id1_2_1_, doctor2_.doctor_id as doctor_i1_3_2_, specialty0_.specialty_name as specialt2_7_0_, doctorspec1_.doctor_id as doctor_i2_2_1_, doctorspec1_.specialty_id as specialt3_2_1_, doctorspec1_.specialty_id as specialt3_2_0__, doctorspec1_.id as id1_2_0__, doctor2_.doctor_cmp as doctor_c2_3_2_, doctor2_.doctor_email_address as doctor_e3_3_2_, doctor2_.doctor_name as doctor_n4_3_2_, doctor2_.doctor_phone_no as doctor_p5_3_2_, doctor2_.doctor_profile_image as doctor_p6_3_2_, doctor2_.status as status7_3_2_ from specialties specialty0_ inner join doctor_specialties doctorspec1_ on specialty0_.specialty_id=doctorspec1_.specialty_id inner join doctors doctor2_ on doctorspec1_.doctor_id=doctor2_.doctor_id where doctor2_.doctor_id=?2021-10-30 21:19:13.565 DEBUG 44504 --- [nio-8080-exec-4] org.hibernate.SQL : select specialty0_.specialty_id as specialt1_7_0_, doctorspec1_.id as id1_2_1_, doctor2_.doctor_id as doctor_i1_3_2_, specialty0_.specialty_name as specialt2_7_0_, doctorspec1_.doctor_id as doctor_i2_2_1_, doctorspec1_.specialty_id as specialt3_2_1_, doctorspec1_.specialty_id as specialt3_2_0__, doctorspec1_.id as id1_2_0__, doctor2_.doctor_cmp as doctor_c2_3_2_, doctor2_.doctor_email_address as doctor_e3_3_2_, doctor2_.doctor_name as doctor_n4_3_2_, doctor2_.doctor_phone_no as doctor_p5_3_2_, doctor2_.doctor_profile_image as doctor_p6_3_2_, doctor2_.status as status7_3_2_ from specialties specialty0_ inner join doctor_specialties doctorspec1_ on specialty0_.specialty_id=doctorspec1_.specialty_id inner join doctors doctor2_ on doctorspec1_.doctor_id=doctor2_.doctor_id where doctor2_.doctor_id=?

没有删除语句...

------------------------编辑 1------------------------

Doctor find = doctorRepository.findById(1).get();

DoctorSpecialties ds1 = new DoctorSpecialties();
ds1.setSpecialty(specialtyRepository.findById(1).get());
ds1.setDoctor(find);

DoctorSpecialties ds2 = new DoctorSpecialties();
ds2.setSpecialty(specialtyRepository.findById(2).get());
ds2.setDoctor(find);

find.getDoctorSpecialties().add(ds1);
find.getDoctorSpecialties().add(ds2);

doctorRepository.save(find);

我做了一些测试,我不能完全理解。我这样做了,它只在我实际添加两个对象时保存了一次。

insert into doctor_specialties (id, doctor_id, specialty_id) values (null, ?, ?)

------------------------编辑 2------------------------

DoctorSpecialties(修改构造函数)

@Entity
@Table(name = "doctor_specialties")
public class DoctorSpecialties implements Serializable {

public DoctorSpecialties(Integer specialtyId, Doctor doctor) {
this.specialty = new Specialty(specialtyId);
this.doctor = doctor;
}

}

Controller

@PostMapping(value = "/saveSpecialties/{id}")
public String saveDoctorSpecialties(@RequestParam(required = false) String[] specialtiesId,
@PathVariable Integer id, RedirectAttributes message) {
if (id != null && id > 0) {

doctorService.saveDelete(id);

Doctor doctor = doctorService.findOne(id);
if (specialtiesId != null && specialtiesId.length > 0) {
for(String idSpecialty : specialtiesId){
doctorSpecialtiesService.save(new DoctorSpecialties(Integer.parseInt(idSpecialty), doctor));
}
}
message.addFlashAttribute("success", "Specialties successfully saved.");
return "redirect:/doctors/profile/{id}/specialties";
}
message.addFlashAttribute("error", "Doctor doesn't exists");
return "redirect:/doctors/list";
}

服务

@Override
@Transactional
public void saveDelete(Integer doctorId) {
Doctor doctor = this.doctorRepository
.findById(doctorId).get();
doctor.getDoctorSpecialties().clear();
}

控制台:

select doctor0_.doctor_id as doctor_i1_3_0_, doctor0_.doctor_cmp as doctor_c2_3_0_, doctor0_.doctor_email_address as doctor_e3_3_0_, doctor0_.doctor_name as doctor_n4_3_0_, doctor0_.doctor_phone_no as doctor_p5_3_0_, doctor0_.doctor_profile_image as doctor_p6_3_0_, doctor0_.status as status7_3_0_ from doctors doctor0_ where doctor0_.doctor_id=?select doctorspec0_.doctor_id as doctor_i2_2_0_, doctorspec0_.id as id1_2_0_, doctorspec0_.id as id1_2_1_, doctorspec0_.doctor_id as doctor_i2_2_1_, doctorspec0_.specialty_id as specialt3_2_1_ from doctor_specialties doctorspec0_ where doctorspec0_.doctor_id=?

update appointments set doctor_specialties_id=null wheredoctor_specialties_id=?

update doctor_schedules setdoctor_specialties_id=null where doctor_specialties_id=?

delete from doctor_specialties where id=?

最佳答案

对于事务中的一对多关系,一旦您获得父项 (Doctor) 并遍历其子项 (DoctorSpecialties) [换句话说,一旦您加载整个父项及其子项进入持久状态],您将无法删除您的 DoctorSpecialties直接通过其 repository .


您可以尝试类似下面的示例来查看它:

@Transactional
public void removeLine(Long doctorId, Long specId) {
Doctor doctor = this.doctorRepository // (1)
.findById(doctorId)
.orElseThrow(IllegalArgumentException::new);
this.doctorSpecialtiesRepository.deleteById(specId); // (2)
}

在 (1) 处,我们加载 doctor进入持久化状态。所以在这里,如果fetch = FetchType.EAGER ,这意味着它将加载 doctor及其全部doctorSpecialties进入持久状态,这个原因 (2) 不会给你带来任何影响。

否则,如果fetch = FetchType.LAZY , 它只加载 doctor进入持久化状态,在(2)时删除成功。

你的情况很相似,虽然fetch = FetchType.LAZY , 但你通过使用 forEach 遍历了 children 然后加载 doctorSpecialties进入持久化状态。这就是您无法删除它们的原因。


建议:使用orphanRemoval = true在你的父实体中

@OneToMany(mappedBy = "doctor", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<DoctorSpecialties> dss;

然后简单地在你的方法中清除它的 child (在@Transactional 方法中)

doctor.getDoctorSpecialties().clear();

关于java - 更新@OneToMany 关系(Spring Boot、Spring Data),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69783532/

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