[英]Spring JPA how to persist parent when the child is persisted in ManyToMany relationship
[英]@ManyToMany is not working from Child-to-Parent using Spring/JPA/REST
我對Java / Spring比較陌生。 我已經使用Spring框架創建了一個非常簡單的測試應用程序。 我一直在嘗試@ JsonIgnore / @ JsonManagedReference / @ JsonBackReference。 我嘗試了許多在線建議,但無法獲取@ManyToMany注釋以雙向工作。
我定義了兩個實體“播放列表”和“歌曲”。 它們之間存在ManyToMany關系。
我將播放列表實體定義為:
@Entity
@Table(name="playlist")
public class Playlist implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer playlistId;
@Id
@GeneratedValue
@Column(name="playlist_id")
public Integer getPlaylistId() {
return playlistId;
}
public void setPlaylistId(Integer playlistId) {
this.playlistId = playlistId;
}
private String name;
private Set<Song> songs = new HashSet<Song>(0);
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name = "playlist_song",
joinColumns = {@JoinColumn(name = "f_playlist_id", referencedColumnName = "playlist_id")},
inverseJoinColumns = {@JoinColumn(name = "f_song_id", referencedColumnName = "song_id")}
)
@JsonManagedReference
public Set<Song> getSongs() {
return songs;
}
public void setSongs(Set<Song> songs) {
this.songs = songs;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
第二實體宋為:
@Entity
@Table(name="song")
public class Song implements Serializable{
public Song() {
}
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer songIdentifier;
private String name;
private Set<Playlist> playlists = new HashSet<Playlist>(0);
@Id
@Column(name="song_id")
@GeneratedValue
public Integer getSongIdentifier() {
return songIdentifier;
}
public void setSongIdentifier(Integer songIdentifier) {
this.songIdentifier = songIdentifier;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany(mappedBy="songs")
@JsonBackReference
public Set<Playlist> getPlaylists() {
return playlists;
}
public void setPlaylists(Set<Playlist> playlists) {
this.playlists = playlists;
}
}
將@Service定義為:
@Service
public class SongServiceImpl implements SongServiceDao {
@Autowired
private SongRepo songRepo;
@Override
public Collection<Song> findAll() {
Collection <Song> allsongs = (Collection<Song>) songRepo.findAll();
return allsongs;
}
}
我定義@Controller為
@RestController
public class M2MController {
@Autowired
SongServiceDao songService;
@RequestMapping(
value = "/test/songs",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Song>> getSongs() {
Collection<Song> songs = songService.findAll();
return new ResponseEntity<Collection<Song>>(songs, HttpStatus.OK);
}
@Autowired
PlaylistServiceDao playlistService;
@RequestMapping(
value = "/test/playlists",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Playlist>> getPlaylists() {
Collection<Playlist> playlists = playlistService.findAll();
return new ResponseEntity<Collection<Playlist>>(playlists, HttpStatus.OK);
}
}
我在MySql中定義架構為
-- -----------------------------------------------------
-- Table `m2mDb`.`playlist`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `m2mDb`.`playlist` (
`playlist_id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NULL,
PRIMARY KEY (`playlist_id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `m2mDb`.`song`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `m2mDb`.`song` (
`song_id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NULL,
PRIMARY KEY (`song_id`),
UNIQUE INDEX `songId_UNIQUE` (`song_id` ASC))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `m2mDb`.`playlist_song`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `m2mDb`.`playlist_song` (
`f_playlist_id` INT NOT NULL,
`f_song_id` INT NOT NULL,
INDEX `toSong_idx` (`f_song_id` ASC),
INDEX `toPlaylist_idx` (`f_playlist_id` ASC),
PRIMARY KEY (`f_playlist_id`, `f_song_id`),
INDEX `secondary` (`f_song_id` ASC, `f_playlist_id` ASC),
CONSTRAINT `toPlaylist`
FOREIGN KEY (`f_playlist_id`)
REFERENCES `m2mDb`.`playlist` (`playlist_id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `toSong`
FOREIGN KEY (`f_song_id`)
REFERENCES `m2mDb`.`song` (`song_id`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
當我運行它時,我得到以下結果:
/ test /歌曲返回:
[
{
"songIdentifier": 1,
"name": "song one"
},
{
"songIdentifier": 2,
"name": "song 2"
},
{
"songIdentifier": 3,
"name": "song 3"
}
]
/ test / playlists返回:
[
{
"playlistId": 1,
"name": "list 1",
"songs": [
{
"songIdentifier": 2,
"name": "song 2"
},
{
"songIdentifier": 3,
"name": "song 3"
},
{
"songIdentifier": 1,
"name": "song one"
}
]
},
{
"playlistId": 2,
"name": "list 2",
"songs": [
{
"songIdentifier": 3,
"name": "song 3"
},
{
"songIdentifier": 1,
"name": "song one"
}
]
}
播放列表返回正確的結果。 我希望歌曲也能包含所有播放列表。
如果有人能闡明我將其弄亂的地方,我將不勝感激。
當您使用@JsonManagedReference
和@JsonBackReference
,會發生什么情況,即在對Song
進行序列化期間,Jackson不會序列化PlayList
的列表,因為該PlayList
已經在XML的另一個級別進行了序列化。
您可以使用的是@JsonIdentityInfo
至少可以使您擁有JSON來輸出PlayList
數組,但要使用與其包含的播放列表關聯的標識符。
[ { "playlistId": 1, "name": "list 1", "songs": [ { "songIdentifier": 2, "name": "song 2" "playLists": [1, 2] } ] },
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.