对于我的任务,我需要使用 JPA 创建多对多关系,但联结表是用额外的列手动指定的。 数据结构如下所示:
- 图书(ID、名称、出版、流派、评级(
- 作者(ID、姓名、性别、出生(
- Book-Author (id, book-id, author-id(
我创建了这样的实体:
作者:
@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "authors")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name", length = 60)
private String name;
@Enumerated(EnumType.STRING)
private Gender gender;
private Date born;
@OneToMany(mappedBy = "author",cascade = CascadeType.ALL, orphanRemoval =
true, fetch = FetchType.EAGER)
private Set<AuthorBook> authorBooks = new HashSet<>();
}
书:
@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "books")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private Date published;
private String genre;
private BigDecimal rating;
@OneToMany(mappedBy = "book",cascade = CascadeType.REMOVE, fetch =
FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<AuthorBook> authorBooks = new HashSet<>();
}
作者:
@Data
@EqualsAndHashCode(exclude = {"book", "author"})
@Entity
@Table(name = "author_book")
public class AuthorBook implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
@JoinColumn(name = "book_id")
private Book book;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "author_id")
private Author author;
}
我插入到表中的数据集:
图书表:
id name published genre rating
1 'Залишенець' '2005-02-03' 'historical novel' '5'
2 'Ключ' '1999-01-01' 'novel' '3'
3 'Effective Java' '2001-03-02' 'technical' '5'
4 'Java Concurrency' '2006-04-23' 'technical' '4'
5 'Java Puzzlers' '2005-02-02' 'technical' '4'
6 'Patterns' '2002-06-25' 'technical' '3'
7 'Harry Potter' '1997-06-26' 'fantasy' '5'
8 'The Programmer' '1999-09-21' 'education' '5'
9 'The Lost Symbol' null 'crime' '4'
作者表:
id name gender born
1 'Шкляр Василь Миколайович' 'male' '1951-06-10'
2 'Joshua Bloch' 'male' '1961-07-28'
3 'Martin Fowler' 'male' null
4 'Chad Fowler' 'male' null
5 'J. K. Rowling' 'female' '1965-07-31'
6 'Dan Brown' 'male' '1964-06-22'
7 'Suzanne Collins' 'female' '1962-08-10'
作者书表:
id book_id author_id
1 1 1
2 2 1
3 3 2
4 4 2
5 5 2
6 6 3
7 9 6
8 8 4
9 7 5
例如,当我删除id=2的书时,它会删除id=1的作者。有没有办法在不删除绑定作者的同时删除书籍。与作者表相同:删除作者时,我不应该删除他的书。我是春季数据JPA的新手,如果这个问题很愚蠢,很抱歉。
更新
我从 AuthorBook 实体@ManyToOne注释中删除级联类型,现在它看起来像这样:
public class AuthorBook implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "book_id")
private Book book;
@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
}
书籍和作者实体保持不变。 现在,当我尝试使用 JPA 的 deleteById(idValue( 删除 id=1 的书时,它会抛出
javax.persistence.EntityNotFoundException: Unable to find Book with id 1
它实际上从书籍表中删除书籍,但不会从 AuthorBook 表中删除相关记录,我的意思是没有 id=1 的书留在书籍表中,但在 AuthorBook 表中仍然有记录:
id book_id author_id
1 1 1
删除id=1的书籍记录后的MySql屏幕截图
作者书表 在此处输入图像描述
书表: 在此处输入图像描述
作者表:在此处输入图像描述
您正在强制实体删除具有此标记的依赖记录(cascade = CascadeType.ALL)
CascadeType.ALL 的含义是持久性会将所有 EntityManager 操作(PERSIST、REMOVE、REFRESH、MERGE、DETACH(传播(级联(到相关实体。
如果您不想删除依赖记录,请从实体中删除此标记,这可能会导致在表中留下孤立记录(不是一个好的做法(。