Cześć,
Tworzę aplikację back-end'ową w Spring do przechowywania informacji o muzykach i albumach muzycznych (baza to postgres). Mam klasę Album
, która jest w relacji Many-To-Many z klasą Band
. Mam problem z "połączeniem" dwóch obiektów tych klas w relacji Many-To-Many. Napisałem do tego klasę z endpoint'em post (funkcja associate
) według przykładu z tej strony: https://www.rbsprogramming.com/articles/spring-boot-crud-web-api/
, ale bez skutku - endpoint zwraca pustą listę, relacja nie powstaje. Byłbym wdzięczny za pomoc w rozwiązaniu problemu. Poniżej zamieszam istotne klasy:
Kontroler AlbumBandController, zawierający funkcję associate
, która powinna "łączyć" w relacji obiekty klas Band
i Album
poprzez podanie odpowiednich id obiektów znajdujących się już w bazie:
@RestController
public class AlbumBandController {
@Autowired
private AlbumRepository albumRepository;
@Autowired
private BandRepository bandRepository;
@PostMapping("/album/{albumId}/band/{bandId}")
public List<Band> associate(@PathVariable Long albumId, @PathVariable Long bandId) {
Band band = this.bandRepository.findById(bandId).orElseThrow(() -> new MissingResourceException("Band", "Band"
, bandId.toString()));
return this.albumRepository.findById(albumId).map((album) -> {
album.getBands().add(band);
return this.albumRepository.save(album).getBands();
}).orElseThrow(() -> new MissingResourceException("Album", "Album", albumId.toString()));
}
}
Klasa Album
:
@Entity
@Table(name="album")
public class Album {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name="title")
private String title;
@ManyToMany(targetEntity = Band.class, mappedBy = "albums")
private List<Band> bands;
@ManyToMany(targetEntity = Musician.class, mappedBy = "albums")
private List<Musician> musicians;
@Embedded
@Column(name="duration")
private Duration duration;
@Column(name="dateofrelease")
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd/MM/yyyy", timezone="CET")
private Date dateOfRelease;
@Column(name="coverpath")
private String coverPath;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Date getDateOfRelease() {
return dateOfRelease;
}
public void setDateOfRelease(Date dateOfRelease) {
this.dateOfRelease = dateOfRelease;
}
public String getCoverPath() {
return coverPath;
}
public void setCoverPath(String coverPath) {
this.coverPath = coverPath;
}
public List<Band> getBands() {
return bands;
}
public void setBands(List<Band> bands) {
this.bands = bands;
}
public List<Musician> getMusicians() {
return musicians;
}
public void setMusicians(List<Musician> musicians) {
this.musicians = musicians;
}
}
Klasa Band
:
@Entity
@Table(name="band")
public class Band {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name="name")
private String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "album_band",
joinColumns = @JoinColumn(name = "album_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "band_id",
referencedColumnName = "id"))
private List<Album> albums;
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<Album> getAlbums() {
return albums;
}
public void setAlbums(List<Album> albums) {
this.albums = albums;
}
}