【发布时间】:2021-05-19 11:46:05
【问题描述】:
早上好,很高兴见到你。
我最近刚接触 Spring Boot,我正在使用一个 REST API,它基本上是一个带有歌曲的播放列表,基本上 REST API 应该具有以下结构。一个播放列表可以包含许多歌曲:
{
"name": "Lista 1",
"description": "Lista de reproduccion 2020 spotify",
"songs": [
{
"title": "Tan Enamorados",
"artist": "CNCO",
"album": "Tan Enamorados",
"year": 2020,
"playList": 1
},
{
"title": "Hawai",
"artist": "Maluma",
"album": "PAPI JUANCHO",
"year": 2020,
"playList": 1
}
]
}
目前这是我配置实体的方式
实体歌曲
@Entity
@Table(name = "SONGS")
public class Songs{
@JsonIgnore
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "ID")
private Long id;
@Column(name = "title")
private String title;
@Column(name = "artist")
private String artist;
@Column(name = "album")
private String album;
@Column(name = "year")
private int year;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PLAY_LIST_ID")
private PlayList playList;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return this.artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getAlbum() {
return this.album;
}
public void setAlbum(String album) {
this.album = album;
}
public int getYear() {
return this.year;
}
public void setYear(int year) {
this.year = year;
}
public PlayList getPlayList() {
return this.playList;
}
public void setPlayList(PlayList playList) {
this.playList = playList;
}
}
实体播放列表
@Entity
@Table(name = "PLAY_LIST")
public class PlayList {
@JsonIgnore
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "ID")
private Long id;
@Column(name="name")
private String name;
@Column(name="description")
private String description;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "playList")
private List<Songs> songs = new ArrayList<>();
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Songs> getSongs() {
return this.songs;
}
public void setSongs(List<Songs> songs) {
this.songs = songs;
}
}
控制器
@RestController
@RequestMapping("playlist")
public class PlayListController {
@Autowired
private PlayListService playListService;
//Get playlist by id with songs belongs that playlist
@GetMapping("/{id}")
public Optional<PlayList> getPlayListByID(@PathVariable(value = "id") Long id) {
Optional<PlayList> playList = playListService.getById(id);
return playList;
}
@PostMapping("/create")
public PlayList createPlayList(@RequestBody PlayList playList) {
return playListService.savePlayList(playList);
}
}
我的班级 PlayListServiceImpl
@Service
public class PlayListServiceImpl implements PlayListService {
@Autowired
private PlayListRepository playListRepository;
public Optional <PlayList> getById(Long Id) {
Optional <PlayList> playList= playListRepository.findById(Id);
return playList;
}
@Override
public PlayList savePlayList(PlayList playList) {
return playListRepository.save(playList);
}
}
我的仓库
@Repository
public interface PlayListRepository extends JpaRepository<PlayList, Long> {
Optional<PlayList> findById(Long Id);
}
但是,当我尝试使用 get 方法获取播放列表时,我遇到了无限递归问题:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.example.api.songs.entity.PlayList[\"songs\"]->org.hibernate.collection.internal.PersistentBag[0]->com.example.api.songs.entity.Songs[\"playList\"]->com.example.api.songs.entity.PlayList[\"songs\"]->org.hibernate.
这是由于在 Songs 实体中找到 playList 字段,当尝试获取包含歌曲的播放列表时,我得到一个递归数组,而不是 playList 的 id,这正是我想要得到的,现实是我得到了这样的东西:
我可以通过在该字段中应用 JsonIgnore 来解决,但这会影响我,当我去保存播放列表时,我无法将 idPlayList 字段传递给每首歌曲以确保每首歌曲都与其各自的 idPlayList 一起保存
我认为最好的办法是在这里建立一个 DTO 来帮助我建立两个表的关系,但是,我不知道在执行 get 时我会如何以允许我的方式做到这一点从播放列表中,仅获取 idPlayList,并且在省电时通过将要与播放列表一起保存的每首歌曲中的 idPlayList,或者如果有另一种方式可以存储播放列表及其歌曲并存储它们直接,因为目前我必须由 BD 为每首歌曲分配 idPlayList
【问题讨论】:
-
public class Songs必须是Song。这是一条记录,不是所有记录:)
标签: sql json spring-boot hibernate jpa