我对实体之间的关系如何工作以及这对我的JPA信息库意味着什么感到困惑。
我有一个名为Loan的类,该类存储每笔贷款的专辑列表。
我有一个贷款库和一个相册库。启动应用程序时,相册存储库中充满了相册。 AlbumId是自动生成的。
当我创建新的贷款并尝试从存储库添加专辑时,出现异常:
由以下原因引起:org.springframework.dao.InvalidDataAccessApiUsageException:传递给持久对象的独立实体:com.library.demo.entity.Album;嵌套的异常是org.hibernate.PersistentObjectException:分离的实体传递给持久化:com.library.demo.entity.Album
如果我创建新贷款并即时添加新专辑,则它会按预期工作。在调试过程中,我意识到这是因为在向贷款中快速添加新相册时albumId为null,大概是因为它将相册添加至存储库并在创建贷款时生成了新的albumId。
我的相册实体如下:
@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;
我的贷款看起来像这样:
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;
我也很困惑专辑为什么必须使用ManyToOne注释来引用贷款。为什么专辑必须引用贷款?
我通常习惯于关系数据库,所以也许我以错误的方式思考事情。如果我只能将新专辑添加到贷款中,那么它将无法达到我想要做的目的。
答案 0 :(得分:0)
Loan and Album tables have a one-to-many relationship.
So in Album your mapping should be like below:
@ManyToOne
@JoinColumn(name = "loan_id")
private Loan loan;
Considering loan_id is the primary key of Loan.
And in Loan your mapping should be like below:
@OneToMany(mappedBy = "loan", cascade = CascadeType.ALL)
private List<Album> albums;
@OneToMany and @ManyToOne defines a one-to-many and many-to-one relationship between 2 entities. @JoinColumn indicates the entity is the owner of the relationship: the corresponding table has a column with a foreign key to the referenced table. mappedBy indicates the entity is the inverse of the relationship
答案 1 :(得分:0)
我已经按照您的描述更新了源代码,并对启动进行了一些更改。
如果我先创建贷款,然后将其保存到贷款存储库中,然后再添加专辑集,则它不再崩溃。
Loan loan = new Loan(1, new Date(), calendar.getTime(),null);
loanRepository.save(loan);
List<Album> albumList = AlbumImport.getAlbumList();
albumRepository.save(albumList);
List<Album> albums = new ArrayList<>();
albums.add(albumList.get(1));
albums.add(albumList.get(5));
loan.setAlbums(albums);
但是,当我运行getLoan测试时,专辑列表为空
答案 2 :(得分:0)
删除层叠=CascadeType。ALL解决了我的问题。