Spring Boot实体,关系和存储库混乱

时间:2018-10-04 07:11:02

标签: spring-boot jpa

我对实体之间的关系如何工作以及这对我的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注释来引用贷款。为什么专辑必须引用贷款?

我通常习惯于关系数据库,所以也许我以错误的方式思考事情。如果我只能将新专辑添加到贷款中,那么它将无法达到我想要做的目的。

3 个答案:

答案 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解决了我的问题。