JPA 多对多与特定级联类型的关系



对于我的任务,我需要使用 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(传播(级联(到相关实体。

如果您不想删除依赖记录,请从实体中删除此标记,这可能会导致在表中留下孤立记录(不是一个好的做法(。

最新更新