gpt4 book ai didi

java - 在 Spring Boot 中使用 JPA 从具有 OneToMany 关系的实体中删除对象

转载 作者:行者123 更新时间:2023-12-04 07:40:09 24 4
gpt4 key购买 nike

下午好,我正在使用 REST API,其中我有一个包含许多歌曲的播放列表,我使用 JPA 以及使我能够在两者之间建立关系的好处。现在,如果我想删除已经添加到播放列表中的歌曲,我不能这样做,我在下面展示我的类(class)
类播放列表

@Entity
@Table(name = "PLAY_LIST")
public class PlayList {

@JsonIgnore
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

//@JsonView(View.Get.class)
@Column(name="name")
private String name;

//@JsonView(View.Get.class)
@Column(name="description")
private String description;

//@JsonView(View.Get.class)
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "playList")
private List<Song> songs = new ArrayList<>();

@Transient
public void addSong(Song song) {
song.setPlayList(this);
songs.add(song);
}

@Transient
public void removeSong(Song song) {
songs.remove(song);
}

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<Song> getSongs() {
return this.songs;
}

public void setSongs(List<Song> songs) {
this.songs = songs;
}

}
这里我有添加歌曲和删除的方法,但是,删除对我不起作用。
类歌
Entity
@Table(name = "SONG")
public class Song{

@JsonIgnore
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

//@JsonView(View.Create.class)
@Column(name = "title")
private String title;

//@JsonView(View.Create.class)
@Column(name = "artist")
private String artist;

//@JsonView(View.Create.class)
@Column(name = "album")
private String album;

//@JsonView(View.Create.class)
@Column(name = "year")
private int year;

/*

Fetch: Esta propiedad se utiliza para determinar cómo debe ser cargada la entidad.
LAZY (perezoso): Indica que la relación solo se cargará cuando la propiedad sea leída por primera vez */
//@JsonView(View.Get.class)
@JsonIgnore
@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;
}

}
我的类(class) Controller
@RestController
@RequestMapping("playlist")
public class PlayListController {

@Autowired
private PlayListService playListService;

@Autowired
private SongRepository songRepository;


// Get playlist by id with songs belongs that playlist

@GetMapping("/get/{id}")
public Optional<PlayList> getPlayListByID(@PathVariable(value = "id") Long id) {

Optional<PlayList> playList = playListService.getById(id);
return playList;
}

@PostMapping("/create")
public PlayList createPlayList(@RequestBody PlayListDTO playListDTO) {

PlayList playList = new PlayList();

playList.setName(playListDTO.getName());
playList.setDescription(playListDTO.getDescription());
playList.setSongs(new ArrayList<>());

for (int x=0; x<playListDTO.getSongs().size(); x++) {

Song songs=new Song();
songs.setTitle(playListDTO.getSongs().get(x).getTitle());
songs.setArtist(playListDTO.getSongs().get(x).getArtist());
songs.setAlbum(playListDTO.getSongs().get(x).getAlbum());
songs.setYear(playListDTO.getSongs().get(x).getYear());
playList.addSong(songs);

}
return playListService.savePlayList(playList);
}
@PutMapping("/update/{id}")
public PlayList updatePlayList(@PathVariable(value = "id") Long id,@RequestBody Song song){

PlayList playList = playListService.getById(id).get();
song.setPlayList(playList);
playList.getSongs().add(song);
playListService.savePlayList(playList);
return playList;
}

@DeleteMapping("/delete/{id}")
public PlayList deletePlayList(@PathVariable(value = "id") Long id,@RequestBody Song song){
PlayList playList =playListService.getById(id).get();
System.out.println(playList.getSongs());
playList.removeSong(song);
System.out.println(playList.getSongs());
return playList;
}

}
所以我正在存储播放列表及其歌曲,方法 POST
{
"name": "Lista 1",
"description": "Lista de reproduccion 2020 spotify",
"songs": [
{
"title": "Tan Enamorados",
"artist": "CNCO",
"album": "Tan Enamorados",
"year": 2020
},
{
"title": "Hawai",
"artist": "Maluma",
"album": "PAPI JUANCHO",
"year": 2020
}
]
}
现在,为了消除我正在传递播放列表的 id 和歌曲的请求(在 BD 中自动创建的没有歌曲 id 的对象),但是,我无法从播放列表中消除歌曲,并且在日志级别它返回这个在控制台打印
例如,我想删除以下歌曲:
enter image description here
但是它没有被删除,它向我返回相同的列表
我是否缺少某些东西可以删除歌曲而不必删除播放列表?

最佳答案

使用 PlayList 中的所有歌曲列表删除一首歌曲并不是一个好主意。 .@OneToMany 没有连接表协会。所以我们可以更简单地删除一首歌,使用 SONG表(这是 @OneToMany 的连接表不方便的主要原因)。
你需要一个歌曲 id 并且你需要使用 CrudRepository.deleteById()方法。
为此,您可以使用完整的组合(标题、艺术家、专辑、年份),但将歌曲 ID 添加到 JSON 会更简单。
最好使用此端点 URL 来删除歌曲/{playListId}/songs/{songId}你不需要delete在 URL 中,您已经使用了 DELETE HTTP 方法。
为什么您的代码不起作用

  • 使用列表中的删除方法不正确
  • @Transient
    public void removeSong(Song song) {
    songs.remove(song);
    }
    songs.remove()找不到 song在列表中, List.remove()通过引用查找歌曲。它需要有一个开放的持久上下文并从中获取一首歌曲才能在列表中找到它。
  • 不使用事务(打开的持久上下文)让 Hibernate 知道一首歌被删除并且 Hibernate 必须更新数据库。

  • 所以一个有效的场景
    start @Transactional
    Spring starts a database transaction
    Spring opens a persistent context
    load PlayList
    load a song from the database (using id or other song attributes)
    delete a song from PlayList songs (or delete a song from PlayList songs using id)
    end @Transactional

    Hibernate flushes changes and delete a song in the database
    persistent context is closed
    database transaction is committed

    关于java - 在 Spring Boot 中使用 JPA 从具有 OneToMany 关系的实体中删除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67527711/

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