Add bidirectional Genre relationship to Album entity
This commit extends the Album entity with bidirectional relationship
management for the AlbumHasGenre join table, enabling many-to-many
associations between albums and genres with convenient helper methods.
Key enhancements:
Relationship Mapping:
- Added OneToMany relationship from Album to AlbumHasGenre
* Bidirectional mapping with cascade ALL and orphan removal
* Maintains collection of album-genre associations
* Initialized as ArrayList to prevent null pointer exceptions
* Follows the same pattern as albumArtists relationship
Helper Methods for Genre Management:
- addGenre(Genre genre):
* Creates AlbumHasGenre join table entry
* Sets bidirectional references to Album and Genre
* Adds association to albumGenres collection
* Simplifies adding genres to albums programmatically
- removeGenre(Genre genre):
* Removes association by comparing genre IDs
* Safely handles null checks
* Uses removeIf for clean collection manipulation
* Maintains referential integrity
- getGenres():
* Convenience method to extract Genre list from join table
* Uses Java streams for clean transformation
* Maps AlbumHasGenre → Genre
* Returns List<Genre> for easy consumption
Collection Management:
- Added getAlbumGenres() getter
* Returns full List<AlbumHasGenre> for direct access
* Useful for repository-level operations
- Added setAlbumGenres() setter
* Allows bulk replacement of genre associations
* Required by JPA for entity hydration
Benefits:
- Enables navigating from Album to associated Genres
- Simplifies genre association management in service layer
- Cascade operations ensure join table entries are managed automatically
- Orphan removal prevents orphaned join table entries
- Consistent API with existing Artist relationship methods
- Type-safe genre management through helper methods
Pattern Consistency:
This implementation mirrors the albumArtists relationship structure,
providing a consistent API for managing both artist and genre associations
on the Album entity. Both relationships use the same cascade and orphan
removal strategies for reliable data integrity.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit message is ready to use in IntelliJ for the Album.java changes!
This commit is contained in:
parent
a102b24ecd
commit
e51d5aa678
|
|
@ -41,6 +41,10 @@ public class Album {
|
||||||
@OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
private List<AlbumHasArtist> albumArtists = new ArrayList<>();
|
private List<AlbumHasArtist> albumArtists = new ArrayList<>();
|
||||||
|
|
||||||
|
// Relacionamento ManyToMany com Genre através da tabela de junção
|
||||||
|
@OneToMany(mappedBy = "album", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
private List<AlbumHasGenre> albumGenres = new ArrayList<>(); // ← ADICIONE ESSA LINHA
|
||||||
|
|
||||||
@Column(name = "created_at", nullable = false, updatable = false)
|
@Column(name = "created_at", nullable = false, updatable = false)
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
|
@ -81,6 +85,31 @@ public class Album {
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== ADICIONE ESSES MÉTODOS PARA GENRE ==========
|
||||||
|
|
||||||
|
// Métodos helper para Genre (ManyToMany)
|
||||||
|
public void addGenre(Genre genre) {
|
||||||
|
AlbumHasGenre albumHasGenre = new AlbumHasGenre();
|
||||||
|
albumHasGenre.setAlbum(this);
|
||||||
|
albumHasGenre.setGenre(genre);
|
||||||
|
albumGenres.add(albumHasGenre);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeGenre(Genre genre) {
|
||||||
|
albumGenres.removeIf(ag ->
|
||||||
|
ag.getGenre() != null && ag.getGenre().getId().equals(genre.getId())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Método conveniente para pegar só os gêneros
|
||||||
|
public List<Genre> getGenres() {
|
||||||
|
return albumGenres.stream()
|
||||||
|
.map(AlbumHasGenre::getGenre)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== FIM DOS MÉTODOS DE GENRE ==========
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
|
|
@ -154,6 +183,18 @@ public class Album {
|
||||||
this.albumArtists = albumArtists;
|
this.albumArtists = albumArtists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== ADICIONE ESSES GETTERS/SETTERS ==========
|
||||||
|
|
||||||
|
public List<AlbumHasGenre> getAlbumGenres() {
|
||||||
|
return albumGenres;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlbumGenres(List<AlbumHasGenre> albumGenres) {
|
||||||
|
this.albumGenres = albumGenres;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== FIM DOS GETTERS/SETTERS DE GENRE ==========
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
public LocalDateTime getCreatedAt() {
|
||||||
return createdAt;
|
return createdAt;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue