I am trying to model a music collection. Insertion works fine, but when I delete an album, it tries to delete the artist as well. If there are other albums from that artist, the foreign key contraint would fail...
Changing
{ CascadeType.ALL } to
{ CascadeType.PERSIST, CascadeType.MERGE } works in Album, but not in Artist: if I then insert a new album, it complains about a transient or non-persisted Artist.
Any pointers would be greatly appreciated. Thanks in advance.
---
An album has many discs, and a disc has many tracks.
The code for Album:
Code:
@Entity
@Table(name = "music_albums")
@SuppressWarnings("serial")
public class Album implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, insertable = false, updatable = false)
private int id;
@Basic(optional = false)
@Column(name = "name", nullable = false, length = 128)
private String name;
@Basic
@Temporal(value = TemporalType.TIMESTAMP)
@Column(name = "released_at")
private Date releasedAt;
@Basic(optional = false)
@Temporal(value = TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false)
private Date createdAt;
@Basic(optional = false)
@Column(name = "rating", nullable = false)
private short rating;
@ManyToMany([b]cascade = { CascadeType.PERSIST, CascadeType.MERGE }[/b], fetch = FetchType.EAGER)
@JoinTable(name = "music_albums_performers", joinColumns = @JoinColumn(name = "album_id", referencedColumnName = "id", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "performer_id", referencedColumnName = "id", nullable = false, updatable = false))
private Set<Artist> performers = new HashSet<Artist>();
@ManyToMany([b]cascade = { CascadeType.PERSIST, CascadeType.MERGE }[/b], fetch = FetchType.EAGER)
@JoinTable(name = "music_albums_composers", joinColumns = @JoinColumn(name = "album_id", referencedColumnName = "id", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "composer_id", referencedColumnName = "id", nullable = false, updatable = false))
private Set<Artist> composers = new HashSet<Artist>();
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
@JoinTable(name = "music_albums_genres", joinColumns = @JoinColumn(name = "album_id", referencedColumnName = "id", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "genre_id", referencedColumnName = "id", nullable = false, updatable = false))
private Set<Genre> genres = new HashSet<Genre>();
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinColumn(name = "album_id", nullable = false)
@org.hibernate.annotations.IndexColumn(name = "position", base = 1)
private List<Disc> discs = new ArrayList<Disc>();
}
The code for Disc:
Code:
@Entity
@Table(name = "music_discs")
@SuppressWarnings("serial")
public class Disc implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, insertable = false, updatable = false)
private int id;
@Basic
@Column(name = "name", length = 128)
private String name;
@Basic(optional = false)
@Column(name = "position", nullable = false, insertable = false, updatable = false)
private short position;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "album_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
private Album album;
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinColumn(name = "disc_id", nullable = false)
@org.hibernate.annotations.IndexColumn(name = "position", base = 1)
private List<Track> tracks = new ArrayList<Track>();
The code for the Track:
Code:
@Entity
@Table(name = "music_tracks")
@SuppressWarnings("serial")
public class Track implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, insertable = false, updatable = false)
private int id;
@Basic(optional = false)
@Column(name = "name", nullable = false, length = 128)
private String name;
@Basic(optional = false)
@Column(name = "position", nullable = false, insertable = false, updatable = false)
private short position;
@Basic(optional = false)
@Column(name = "length", nullable = false)
private int length;
@Basic(optional = false)
@Column(name = "rating", nullable = false)
private short rating;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "disc_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
private Disc disc;
@ManyToMany([b]cascade = { CascadeType.ALL }[/b], fetch = FetchType.EAGER)
@JoinTable(name = "music_tracks_performers", joinColumns = @JoinColumn(name = "track_id", referencedColumnName = "id", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "performer_id", referencedColumnName = "id", nullable = false, updatable = false))
private Set<Artist> performers = new HashSet<Artist>();
@ManyToMany([b]cascade = { CascadeType.ALL }[/b], fetch = FetchType.EAGER)
@JoinTable(name = "music_tracks_composers", joinColumns = @JoinColumn(name = "track_id", referencedColumnName = "id", nullable = false, updatable = false), inverseJoinColumns = @JoinColumn(name = "composer_id", referencedColumnName = "id", nullable = false, updatable = false))
private Set<Artist> composers = new HashSet<Artist>();