gpt4 book ai didi

java - 如何使用 Spring Data Jpa OneToMany 嵌套模型对 Spring Boot Restful API 进行 CURD 操作?

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

我试图制作一个 CRUD 应用程序,它有两个类型为“肌肉”和“锻炼”的模型对象。基本上一个肌肉对象可以有一个锻炼对象列表。我想为两个模型对象实现 CRUD 操作。对于 Muscle 对象,它非常简单,但对于放置/更新操作的练习对象,我收到以下错误“JSON 解析错误:未解析的前向引用:;嵌套异常是 com.fasterxml.jackson.databind.deser.UnresolvedForwardReference ”。此外,如果我尝试删除一项锻炼,不知何故,所有肌肉和锻炼的数据都会被删除。

这是我的肌肉等级

    package com.fazla.exercise.model;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;


@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Muscle {

@Id
// @Column(unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column
private String name;

@OneToMany(mappedBy="muscle", cascade= CascadeType.ALL, fetch = FetchType.EAGER)
// @JoinColumn(name="muscle_id")
// @Column(nullable = true)
private List<Exercise> exercises = new ArrayList<>();

public Muscle() {

}

public Muscle(String name, List<Exercise> exercises) {
super();
this.name = name;
this.exercises = exercises;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List<Exercise> getExercises() {
return exercises;
}

public void setExercises(List<Exercise> exercises) {
this.exercises = exercises;
}

// @Override
// public String toString() {
// return "Muscle [id=" + id + ", name=" + name + ", exercises=" + exercises + "]";
// }



}

这是我的练习对象

    package com.fazla.exercise.model;

import javax.persistence.CascadeType;
import javax.persistence.Column;
//import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;

@Entity
//@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Exercise {
@Id
@Column(unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@Column
private String name;

@Column
private String description;


//As there will be many exercise under one muscle that is why manytoone
//object references an unsaved transient instance - save the transient instance before flushing
//that is why need to add the cascading dependencies
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="muscle_id")
// @JsonIgnore
// @JoinTable(name="muscle")
private Muscle muscle;

public Exercise() {

}

public Exercise(String name, String description, Muscle muscle) {
super();
this.name = name;
this.description = description;
this.muscle = muscle;
}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public Muscle getMuscle() {
return muscle;
}

public void setMuscle(Muscle muscle) {
this.muscle = muscle;
}

// @Override
// public String toString() {
// return "Exercise [id=" + id + ", name=" + name + ", description=" + description + ", muscle=" + muscle + "]";
// }



}

这是肌肉 Controller

package com.fazla.exercise.controller;

import java.util.List;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.fazla.exercise.model.Muscle;
import com.fazla.exercise.repository.MuscleRepository;

@RestController
public class MuscleController {

private MuscleRepository muscleRepository;

public MuscleController(MuscleRepository muscleRepository) {

this.muscleRepository = muscleRepository;
}

@GetMapping("/muscle")
List<Muscle> all(){
return muscleRepository.findAll();
}

@PostMapping("/muscle")
Muscle newMuscle(@RequestBody Muscle muscle) {
return muscleRepository.save(muscle);
}

@GetMapping("/muscle/{id}")
Muscle one(@PathVariable Long id) {
return muscleRepository.findById(id)
.orElse(null);
}

@PutMapping("/muscle/{id}")
Muscle updateMuscle(@RequestBody Muscle newMuscle, @PathVariable Long id) {
return muscleRepository.findById(id)
.map(muscle ->{
muscle.setName(newMuscle.getName());
muscle.setExercises(newMuscle.getExercises());
return muscleRepository.save(muscle);
})
.orElse(null);
}

@DeleteMapping("/muscle/{id}")
void deleteMuscle(@PathVariable Long id){
muscleRepository.deleteById(id);
}

}

这是ExerciseController类

package com.fazla.exercise.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fazla.exercise.model.Exercise;
import com.fazla.exercise.model.Muscle;
import com.fazla.exercise.repository.ExerciseRepository;
import com.fazla.exercise.repository.MuscleRepository;

@RestController
public class ExerciseController {

private ExerciseRepository repository;

private MuscleRepository muscleRepository;

@Autowired
public ExerciseController(ExerciseRepository repository, MuscleRepository muscleRepository) {
super();
this.repository = repository;
this.muscleRepository=muscleRepository;
}

@GetMapping("/exercise")
public List<Exercise> getAll() {
return repository.findAll();
}

@PostMapping("/exercise")
public Exercise newExercise(@RequestBody Exercise newExercise, @RequestParam
Long muscleId) {

Muscle muscle = muscleRepository.findById(muscleId).orElse(null);
newExercise.setMuscle(muscle);

return repository.save(newExercise);
}

@DeleteMapping("/exercise/{id}")
public void deleteExercise(@PathVariable Long id) {
repository.deleteById(id);
}

@GetMapping("/exercise/{id}")
public Exercise one(@PathVariable Long id) {
return repository.findById(id).orElse(null);
}

@PutMapping("/exercise/{id}")
public Exercise updateExercise(@RequestBody Exercise newExercise, @PathVariable Long id) {
return repository.findById(id)
.map(//map a function which maps
e ->{
e.setName(newExercise.getName());
e.setDescription(newExercise.getDescription());
e.setMuscle(newExercise.getMuscle());
return repository.save(e);
})
.orElse(null);
}
}

这是我的ExerciseRepository

包 com.fazla.exercise.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.fazla.exercise.model.Exercise;

public interface ExerciseRepository extends JpaRepository<Exercise, Long> {

}

这是 MuscleRepository

包 com.fazla.exercise.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.fazla.exercise.model.Muscle;

public interface MuscleRepository extends JpaRepository<Muscle, Long>{

}

如果我尝试放置请求或更新练习对象,就会出现此错误

"timestamp": "2018-10-10T06:30:46.924+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: (PushbackInputStream); line: 23, column: 1]Object id [1] (for `com.fazla.exercise.model.Muscle`) at [Source: (PushbackInputStream); line: 13, column: 28], Object id [1] (for `com.fazla.exercise.model.Muscle`) at [Source: (PushbackInputStream); line: 19, column: 28].",
"path": "/api/exercise/14"

最佳答案

解决方案是在 Parent/Muscle 模型上添加 orphanRemoval= true

    @OneToMany(mappedBy="muscle", cascade= CascadeType.ALL, orphanRemoval= true)
private List<Exercise> exercises = new ArrayList<>();

删除子/练习模型中的cascade= CascadeType.ALL

@ManyToOne
private Muscle muscle;

对于 updateExercise,通过查找锻炼所属的肌肉和muscleRepository.findById(muscleId) 并将其设置在新的锻炼对象中来更改请求。

    @PutMapping("/exercise/{id}")
public Exercise updateExercise(@RequestBody Exercise newExercise, @PathVariable Long id, @RequestParam Long muscleId) {
Muscle muscle = muscleRepository.findById(muscleId).orElse(null);
return repository.findById(id)
.map(//map a function which maps
e ->{
e.setName(newExercise.getName());
e.setDescription(newExercise.getDescription());
e.setMuscle(muscle);
return repository.save(e);
})
.orElse(null);
}

关于java - 如何使用 Spring Data Jpa OneToMany 嵌套模型对 Spring Boot Restful API 进行 CURD 操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52734110/

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