对于我的任务,我需要使用JPA创建多对多关系,但必须使用额外的列手动指定联结表。 数据结构如下:
我创建了这样的实体:
作者:
@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<>();
}
AuthorBook:
@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;
}
我插入到表中的数据集:
Books表:
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'
AuthorBook表:
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的作者。有什么办法可以删除书而不删除绑定作者。与作者表相同:删除作者时,我不应该删除他的书。我是Spring Data 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;
}
Book和Author实体保持不变。 现在,当我尝试使用JPA的deleteById(idValue)删除ID = 1的书时,它会抛出
javax.persistence.EntityNotFoundException: Unable to find Book with id 1
它实际上是从books表中删除书,但没有从AuthorBook表中删除关联的记录,我的意思是没有id = 1的书留在books表中,但是在AuthorBook表中仍然有记录:
id book_id author_id
1 1 1
删除ID = 1的图书记录后的MySql屏幕截图
AuthorBook表 enter image description here
答案 0 :(得分:0)
您正在强制实体使用此标签删除从属记录
(cascade = CascadeType.ALL)
CascadeType.ALL的含义是,持久性会将所有EntityManager操作(PERSIST,REMOVE,REFRESH,MERGE,DETACH)传播(层叠)到相关实体。
如果您不想删除从属记录,请从实体中删除此标记,这可能会导致在表中留下孤立记录(不是一个好习惯)。