我查看了一堆類似問題的答案,但沒有找到一個可以為我解決問題的答案。我現在感覺完全迷失了。
我正在開發一個 Spring Boot Web 應用程式,使用 Spring Data JPA 進行持久性。當我嘗試對現有物體進行更新時收到以下錯誤:
org.hibernate.PersistentObjectException:分離的物體傳遞給堅持:com.project.timefit.model.WeeklyRoutinePlan
我正在嘗試使用 crudRepository 編輯物體 WeeklyRoutinePlan(get、create 和 delete 方法作業正常)。
這是我服務中的方法
@Override
@Transactional
public void editRoutinePlan(WeeklyRoutinePlan routinePlan, String username) {
WeeklyRoutinePlan oldRoutinePlan = weeklyRoutinePlanRepository.findById(routinePlan.getId()).get();
oldRoutinePlan.setWeekDay(routinePlan.getWeekDay());
weeklyRoutinePlanRepository.save(oldRoutinePlan);
}
為了除錯,我已經對其進行了簡化,通常我會進行用戶名驗證并映射其他欄位。我仍然得到這個簡化版本的錯誤。如果我不改變作業日,我什至會得到它。
我的物體本身看起來像這樣
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
public class WeeklyRoutinePlan{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private Routine routine;
private LocalTime startTime;
private LocalTime endTime;
private Integer weekDay;
@ManyToOne
private Program program;
public void setRoutine(Routine routine) {
if(routine == this.routine){
return;
}
if(this.routine != null){
this.routine.getWeeklyRoutinePlans().remove(this);
}
if(!routine.getWeeklyRoutinePlans().contains(this)){
routine.getWeeklyRoutinePlans().add(this);
}
this.routine = routine;
}
public void setProgram(Program program) {
if(program == this.program){
return;
}
if(this.program != null){
this.program.getWeeklyRoutines().remove(this);
}
if(!program.getWeeklyRoutines().contains(this)){
program.getWeeklyRoutines().add(this);
}
this.program = program;
}
}
這里是相關物體(雖然我不確定這是否相關,因為我什至沒有更新關系)
常規
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Routine {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private User user;
private String name;
private Integer numberOfCycles;
private Color color;
@ManyToMany(mappedBy = "routines")
private List<Exercise> exercises;
@OneToMany(mappedBy = "routine", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<WeeklyRoutinePlan> weeklyRoutinePlans = new ArrayList<>();
@OneToMany(mappedBy = "routine", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<FrequencyRoutinePlan> frequencyRoutinePlans = new ArrayList<>();
@OneToMany(mappedBy = "routine", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<IndividualRoutinePlan> individualRoutinePlans = new ArrayList<>();
public void remove(){
exercises.forEach(exercise -> exercise.getRoutines().remove(this));
exercises = new ArrayList();
}
public void setExercises(List<Exercise> exercises){
exercises.forEach(e -> {
if(e.getRoutines().stream().noneMatch(r -> Objects.equals(r.getId(), this.getId())))
e.getRoutines().add(this);
});
this.exercises = exercises;
}
public void setWeeklyRoutinePlans(List<WeeklyRoutinePlan> weeklyRoutinePlans) {
if(weeklyRoutinePlans == this.weeklyRoutinePlans){
return;
}
this.weeklyRoutinePlans.forEach(r -> {if(!weeklyRoutinePlans.contains(r))r.setRoutine(null);});
weeklyRoutinePlans.forEach(r -> {if(weeklyRoutinePlans.contains(r))r.setRoutine(this);});
this.weeklyRoutinePlans = weeklyRoutinePlans;
}
public void setFrequencyRoutinePlans(List<FrequencyRoutinePlan> frequencyRoutinePlans) {
if(frequencyRoutinePlans == this.frequencyRoutinePlans){
return;
}
this.frequencyRoutinePlans.forEach(r -> {if(!frequencyRoutinePlans.contains(r))r.setRoutine(null);});
frequencyRoutinePlans.forEach(r -> {if(frequencyRoutinePlans.contains(r))r.setRoutine(this);});
this.frequencyRoutinePlans = frequencyRoutinePlans;
}
public void setIndividualRoutinePlans(List<IndividualRoutinePlan> individualRoutinePlans) {
if(individualRoutinePlans == this.individualRoutinePlans){
return;
}
this.individualRoutinePlans.forEach(r -> {if(!individualRoutinePlans.contains(r))r.setRoutine(null);});
individualRoutinePlans.forEach(r -> {if(individualRoutinePlans.contains(r))r.setRoutine(this);});
this.individualRoutinePlans = individualRoutinePlans;
}
@Override
public String toString() {
return "Routine{"
"id=" id
", user=" user.getUsername()
", name='" name '\''
", numberOfCycles=" numberOfCycles
", color=" color
'}';
}
}
程式
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class Program {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private ProgramSetting programSetting = ProgramSetting.WEEKLY;
private Integer frequency = 1;
@OneToMany(mappedBy = "program", cascade = CascadeType.ALL, orphanRemoval = true)
private List<WeeklyRoutinePlan> weeklyRoutines = new ArrayList<>();
@OneToMany(mappedBy = "program", cascade = CascadeType.ALL, orphanRemoval = true)
private List<FrequencyRoutinePlan> frequencyRoutines = new ArrayList<>();
@OneToMany(mappedBy = "program", cascade = CascadeType.ALL, orphanRemoval = true)
private List<IndividualRoutinePlan> individualRoutines = new ArrayList<>();
@ManyToOne
private User user;
public void setWeeklyRoutines(List<WeeklyRoutinePlan> weeklyRoutines) {
if(weeklyRoutines == this.weeklyRoutines){
return;
}
this.weeklyRoutines.forEach(r -> {if(!weeklyRoutines.contains(r))r.setProgram(null);});
weeklyRoutines.forEach(r -> {if(weeklyRoutines.contains(r))r.setProgram(this);});
this.weeklyRoutines = weeklyRoutines;
}
public void setFrequencyRoutines(List<FrequencyRoutinePlan> frequencyRoutines) {
if(frequencyRoutines == this.frequencyRoutines){
return;
}
this.frequencyRoutines.forEach(r -> {if(!frequencyRoutines.contains(r))r.setProgram(null);});
frequencyRoutines.forEach(r -> {if(frequencyRoutines.contains(r))r.setProgram(this);});
this.frequencyRoutines = frequencyRoutines;
}
public void setIndividualRoutines(List<IndividualRoutinePlan> individualRoutines) {
if(individualRoutines == this.individualRoutines){
return;
}
this.individualRoutines.forEach(r -> {if(!individualRoutines.contains(r))r.setProgram(null);});
individualRoutines.forEach(r -> {if(individualRoutines.contains(r))r.setProgram(this);});
this.individualRoutines = individualRoutines;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Program{"
"id=" id
", name='" name '\''
", programSetting=" programSetting
", frequency=" frequency
", user=" user.getUsername()
'}';
}
}
在這一點上我有點絕望,因為我的其他物體作業正常,我只是不明白我做錯了什么。該方法是事務性的,因此當我進行保存時不應分離物體。
如果我沒有明確呼叫 save ,我會遇到同樣的問題,因為無論如何這是由框架完成的。
我已經嘗試將關系上的獲取設定為 LAZY,我也嘗試過 EAGER,我嘗試讓 Program 上的級聯僅 REMOVE,即使最佳實踐是全部但我讀到有些人對 PERSIST 有問題.
我已經確保我的設定器正確更新了關系,盡管正如我所說我已經簡化了更新,所以我什至沒有使用它們。
我不知所措
uj5u.com熱心網友回復:
評論中的回答:
您將一個實體WeeklyRoutinePlan(routinePlan)傳遞給該方法。我猜這是分離的,因為它是在其他地方加載的。您能否嘗試將 id 直接作為 Long ( routinePlan.getId()) 傳遞。或者嘗試合并routinePlan并再次分配合并的物體routinePlan。
-> 所以問題是我從 DTO 創建的物體有一個 ID,因此即使我沒有嘗試保存那個物體,它也算作一個分離的物體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/480241.html
下一篇:乳膠嵌套回圈未正確顯示
