当前位置: 首页 > 知识库问答 >
问题:

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

单喜
2023-03-14

对于我的任务,我需要使用JPA创建多对多的关系,但是连接表是手动指定的,并带有额外的列。数据结构如下所示:

  • 图书(id、名称、已出版、流派、评级)
  • 作者(身份证、姓名、性别、出生)
  • 图书-作者(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'

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的book,它将删除ID=1的author。有没有什么方法可以在不删除已绑定作者的同时删除书籍。与author表相同的是:删除author时,我不应该删除他的书。我是Spring Data JPA的新手,如果这个问题是愚蠢的,那么很抱歉。

更新

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的book,它抛出

javax.persistence.EntityNotFoundException: Unable to find Book with id 1

它实际上从books表中删除了book,但没有从AuthorBook表中删除关联的记录,我的意思是books表中没有ID=1的book,但AuthorBook表中仍然有记录:

id   book_id   author_id
1     1         1 

ID=1的图书记录删除后的MySql截图

图书表:在此输入图像说明

作者表:在此输入图像描述

共有1个答案

荆炳
2023-03-14

您正在强制实体删除具有此标记(cascade=cascadeType.all)的从属记录

CascadeType.all的含义是持久性将所有EntityManager操作(PERSIST、REMOVE、REFRESH、MERGE、DETACH)传播(级联)到相关实体。

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

 类似资料:
  • 我目前正在开发一个网络票证系统,并有课程来存储我的票证数据。每个票据都可以有多个相关标签,为了管理这些标签,我创建了一个标签编辑器。这很好,只缺少一个删除选项。到目前为止,大多数删除都失败了,原因是该标签仍然被另一个票证引用,这需要先删除它。在寻找解决方案的过程中,我遇到了CascadeType。删除,这似乎正是我想要的。 但是,由于ticket对象包含一组标签,而不是相反,因此每次我删除一张ti

  • 问题内容: 我正在使用JPA 2.0并hibernate。我有一个用户类和一个组类,如下所示: 然后,我创建一个用户和组,然后将该用户分配给该组。 我要拥有的是删除组时(当然),该组将被删除,并且该组具有的所有用户-组关系将从USER_GROUP连接表中自动删除,但用户本身不会从USER表。 使用上面的代码,当我删除组时,只有GROUP表中的行将被删除,并且用户在USER_GROUP连接表中仍然具

  • 我有两个JPA实体(账户和个人),具有双向关系: 当我持久化一个人时,我不想持久化所有帐户,但当我持久一个帐户时,我想更新Person属性hasAccounts,因此我还需要更新这个人。 我做了以下步骤: 创建人员 坚持该人 创建帐户 修改所有者(以前创建的 持久帐户(我希望它会自动合并该人) 我得到了这个例外: (我用JPA 1.0配合Hibernate)。

  • 使用Spring Boot 1.4.0和MySql 5.7 我有两个table并且它是单向的@manytomany,但是在角色的父端,我想删除权限hibernate会自动删除它自己和link-table记录: > 权限