I am confused as to how relationships work in entities and what this means with regard to my JPA repository.
I have a class called Loan which stores a list of albums for each loan.
I have a loan repository and an album repository. The album repository is filled with albums when I start the application. The albumId is autogenerated.
When I create a new loan and try to add an album from the repository I get an exception :
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.library.demo.entity.Album; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.library.demo.entity.Album
If I create a new loan and add a new album on the fly then it works as expected. During the debug I realised that this is because albumId is null when adding a new album on the fly to the loan, presumably because it adds the album to the repository and generates a new albumId when the loan is created.
My album entity looks like this :
@Entity
public class Album implements Serializable {
private static final long serialVersionUID = 0x63A6DA99AA12AAA8L;
@Column @GeneratedValue(strategy = GenerationType.AUTO) @Id private Integer albumId;
@Column (unique=true) private String barcode;
@Column private String band;
@Column private String title;
@Column private String genre;
@Column private Integer year;
@Column private String artworkFilename;
@Column private Boolean enabled;
@Column private Boolean isLoanable;
@Column private Integer numberOfCopies;
@ManyToOne
private Loan loan;
And my loan looks like this :
public class Loan implements Serializable {
private static final long serialVersionUID = 0x62B6DA99AA12AAA8L;
public void setLoanId(Integer loanId) {
this.loanId = loanId;
}
@Column @GeneratedValue(strategy = GenerationType.AUTO) @Id private Integer loanId;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Album> albums= new ArrayList<>();
@Column private Integer customerId;
@Column private Date dateLoaned;
@Column private Date dateToReturn;
@Column private Boolean expired;
I am also confused as to why the album has to refer back to the loan with a ManyToOne annotation. Why does the album have to refer to the loan?
I am mostly used to relation databases so maybe I am thinking about things in the wrong way. If I can only add new albums to the loan then it defeats the purpose of what I am trying to do.