簡體   English   中英

Spring 引導 - 添加歌曲后無法使用從 Postman 獲取:NoSuchElementException (Spring) 和內部服務器錯誤(郵遞員)

[英]Spring Boot - Cannot use get from Postman after adding a song: NoSuchElementException (Spring) and Internal Server Error (postman)

我們的老師要求我們創建一個 spring 引導應用程序來管理具有一對多關系的歌曲和專輯使用 DTO,但是我們需要在 controller 中手動進行映射,我們不能使用外部庫。 關鍵是,無論我如何嘗試更改方法,它總是會導致 Spring 錯誤(我們使用 PostgreSQL 並且在 pgadmin 中我可以毫無問題地看到數據)。

例如,使用我現在共享的代碼,我最初可以使用獲取歌曲和專輯,但如果我添加一首新歌曲,則獲取方法會導致 NoSuchElementException,

特別是這一行: at com.newplaylist.controller.SongController.getSongs(SongController.java:55)

指向這一行: songs.add(new SongDTO((Song) iterator.next(), iterator.next().getAlbum()));

並且我還在 Postman 上收到 500 內部服務器錯誤。在此先感謝您的幫助,如果需要,我可以添加完整的異常跟蹤。

  • 宋DTO

import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;

public class SongDTO {

    private Integer id;
    private String author, title;
    private AlbumDTO album;
    
    public SongDTO() {
            
    }
    
    public SongDTO(Song song) { 
        this.id = song.getId();
        this.author = song.getAuthor();
        this.title = song.getTitle();
    }
    
    public SongDTO(Song song, Album album) {    
        this.id = song.getId();
        this.author = song.getAuthor();
        this.title = song.getTitle();
        this.album = new AlbumDTO(album, true);
    }
    
    // getters and setters...

}
  • 相冊DTO

import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;

public class AlbumDTO {
    
    private Integer id;
    private String name;
    private String production;
    private Set<SongDTO> songs;
    
    public AlbumDTO() {
    }
    
    public AlbumDTO(Album album) {
        this.id = album.getId();
        this.name = album.getName();
        this.production = album.getProduction();
    }
    
    public AlbumDTO(Album album, boolean lazy) {
        this.id = album.getId();
        this.name = album.getName();
        this.production = album.getProduction();
        songs = new HashSet<SongDTO>();
        album.getSongs();
        
        if (!lazy) {
            for (Iterator<Song> iterator = album.getSongs().iterator(); iterator.hasNext();) {
                songs.add(new SongDTO((Song) iterator.next()));
            }
        }
    }

    // getters and setters...

}
  • 歌曲控制器
package com.newplaylist.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.newplaylist.dto.AlbumDTO;
import com.newplaylist.dto.SongDTO;
import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;
import com.newplaylist.service.SongService;

@RestController
@RequestMapping("/song")
public class SongController {

    @Autowired
    SongService songService;
    
    public void init() {
    }
    
    @PostMapping("/add")
    public ResponseEntity<?> addSong(@RequestBody Song song) {
        try {
            return new ResponseEntity<SongDTO>(new SongDTO(songService.addSong(song), song.getAlbum()), HttpStatus.CREATED);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<Object>(e.getStackTrace(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    @GetMapping("/all")
    public ResponseEntity<Collection<SongDTO>> getSongs() {
        Collection<SongDTO> songs = new ArrayList<>();
        
        try {
            for (Iterator<Song> iterator = songService.getSongs().iterator(); iterator.hasNext();) {
                songs.add(new SongDTO((Song) iterator.next(), iterator.next().getAlbum()));
            }
            
            return new ResponseEntity<Collection<SongDTO>>(songs, HttpStatus.OK);
            
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
}
  • 專輯控制器
package com.newplaylist.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.newplaylist.dto.AlbumDTO;
import com.newplaylist.dto.SongDTO;
import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;
import com.newplaylist.service.AlbumService;

@RestController
@RequestMapping("/album")
public class AlbumController {

    @Autowired
    AlbumService albumService;
    
    @PostMapping("/add")
    public ResponseEntity<?> addAlbum(@RequestBody Album album) {
        try {
            return new ResponseEntity<AlbumDTO>(new AlbumDTO(albumService.addAlbum(album), true), HttpStatus.CREATED);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<Object>(e.getStackTrace(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    @GetMapping("/all")
    public ResponseEntity<Collection<AlbumDTO>> getAlbums() {
        Collection<AlbumDTO> albums = new ArrayList<>();
        
        try {
            for (Iterator<Album> iterator = albumService.getAlbums().iterator(); iterator.hasNext();) {
                albums.add(new AlbumDTO((Album) iterator.next(), false));
            }

            return new ResponseEntity<Collection<AlbumDTO>>(albums, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        
    }

}
  • 相冊(實體)
package com.newplaylist.entity;

import java.util.Set;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;

@Entity
public class Album {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String production;
    
    
    //@JsonBackReference        // per scegliere quale reference stampare, altrimenti andrebbe in loop infinito
    @OneToMany(mappedBy = "album", cascade = CascadeType.ALL)
    private Set<Song> songs;
    
    public Album() {
        super();
    }

    public Album(Integer id, String name, String production, Set<Song> songs) {
        super();
        this.id = id;
        this.name = name;
        this.production = production;
        this.songs = songs;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getProduction() {
        return production;
    }

    public void setProduction(String production) {
        this.production = production;
    }

    public Set<Song> getSongs() {
        return songs;
    }

    public void setSongs(Set<Song> songs) {
        this.songs = songs;
    }
    
}
  • 歌曲(實體)

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;

@Entity
public class Song {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String author, title;
    
//  @OneToOne
//  @JoinColumn(name = "album")     // campo album della tab song. questo campo contiene un id che si collega all'entità Album, perciò fai l'inner join con essa.
//  private Album album;
    
//  @ManyToOne
//  @JoinColumn(name = "playlist")
//  private Playlist playlist;
    
    @ManyToOne
    @JoinColumn(name = "album", nullable = false)
    //@JsonManagedReference
    private Album album;
    
    public Song() {}

    public Song(Integer id, String author, String title) {
        super();
        this.id = id;
        this.author = author;
        this.title = title;
    }

    public Song(Integer id, String author, String title, Album album) {
        super();
        this.id = id;
        this.author = author;
        this.title = title;
        this.album = album;
    }

    // getters and setters
    
}

我認為問題出在其中一個類中,但如果您需要其他內容,我可以將項目上傳到 GitHub。

你需要這樣的東西

 try {
        for (Iterator<Song> iterator = songService.getSongs().iterator(); iterator.hasNext();) {
            Song currentSong = iterator.next();
            songs.add(new SongDTO(currentSong, currentSong.getAlbum()));
        }

調用 iterator.next() 將始終獲取一首新歌曲,這意味着 iterator.next().getAlbum() 將獲取與集合中的下一首歌曲相對應的專輯,而不是您已經獲取的當前歌曲第一次調用 iterator.next()。 此外,如果您的歌曲數量為奇數,則會導致異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM