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

对多对多关系应用级联类型删除

郎曾笑
2023-03-14

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

但是,由于ticket对象包含一组标签,而不是相反,因此每次我删除一张ticket时,所有标签都会消失,而不是相反。在阅读了CascadeType的文档之后,这似乎很明显,但我现在不知道如何达到相反的效果。我想创建一个引用来引用所有使用我的标签的票据,尽管这看起来像是将相同的数据存储了两次。

我的票看起来像这样:


@Entity
@Data
@NoArgsConstructor
public class Ticket {
    @Id
    @Column(length = 40)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false)
    private String title;

    @OneToMany(targetEntity = TicketEntry.class, mappedBy = "ticket", orphanRemoval = true, fetch = FetchType.EAGER)
    private List<TicketEntry> entries = new ArrayList<>();

    @Column
    private Status status = Status.OPEN;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "ticket_labels",
            joinColumns = { @JoinColumn(name = "ticket_id")},
            inverseJoinColumns = { @JoinColumn(name = "label_id" )}
    )
    private Set<TicketLabel> labels = new HashSet<>();
}

标签如下:

@Entity
@Data
@NoArgsConstructor
public class TicketLabel {

    @Id
    @Column(length = 40)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name = "";

    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
    @JoinTable(name = "ticket",
            joinColumns = { @JoinColumn(name = "label_id")},
            inverseJoinColumns = { @JoinColumn(name = "ticket_id" )}
    )
    private Set<Ticket> tickets = new HashSet<>();
}

但是这仍然不起作用。我甚至需要在我的标签对象中引用我所有的票吗?或者我可以以某种方式使用“反向删除”级联类型吗?

共有1个答案

穆锋
2023-03-14

您的多对多映射意味着您有两个交集表票证和ticket_labels。我打赌你不想这样,你只需要一个。对于双向映射,您可能有:

public class TicketLabel {
//...
   @ManyToMany(mappedBy = "labels", cascade {CascadeType.MERGE, CascadeType.PERSIST})
   private Set<Ticket> tickets = new HashSet<>();
}
//...

public class Ticket {
// ...
   @ManyToMany
   @JoinTable(name = "ticket_labels",
       joinColumns = { @JoinColumn(name = "ticket_id")},
       inverseJoinColumns = { @JoinColumn(name = "label_id" )}
   )
   private Set<TicketLabel> labels = new HashSet<>();

   public void removeLabel(Label label) {
      labels.remove(label);
      label.getTickets().remove(this);
   }

   public void addLabel(Label label) {
      labels.add(label);
      label.getTickets().add(this);
   }
// ...
}

你必须手动同步标签和票证的帮助删除和添加方法,如本线程所述。要去掉标签,你必须把它从所有的票上去掉。级联型。在这种情况下,移除将导致整个关联的移除。

 类似资料:
  • 对于我的任务,我需要使用JPA创建多对多的关系,但是连接表是手动指定的,并带有额外的列。数据结构如下所示: 图书(id、名称、已出版、流派、评级) 作者(身份证、姓名、性别、出生) 图书-作者(id,book-id,author-id) 我创建了这样的实体: 作者: 书: AuthorBook表: 例如,当我删除ID=2的book,它将删除ID=1的author。有没有什么方法可以在不删除已绑定作

  • 问题内容: 我在我的数据库3个表:,和 学生可以有多个课程,课程可以有多个学生。和之间存在多对多关系。 我为我的项目和课程添加了3个案例。 (a)当我添加用户时,它会保存得很好, (b)当我为学生添加课程时,它会在-预期行为中创建新的行。 (三)当我试图删除学生,则在删除适当的记录和,但它也删除其中不需要的记录。即使课程中没有任何用户,我也希望课程在那里。 下面是我的表和注释类的代码。 这是Hib

  • 问题内容: 我在我的数据库3个表:,和 学生可以有多个课程,课程可以有多个学生。和之间存在多对多关系。 我为我的项目和课程添加了3个案例。 (a)当我添加用户时,它会保存得很好, (b)当我为学生添加课程时,它将在-预期行为中再次创建新行。 (三)当我试图删除学生,则在删除适当的记录和,但它也删除其中不需要的记录。即使课程中没有任何用户,我也希望课程在那里。 下面是我的表和注释类的代码。 这是Hi

  • 问题内容: 我有两个与多对多关联的表。 —数据库片段: 加载 ID 名称 会话 ID 日期 sessionsloads LoadId 的SessionID —hibernate映射片段: 为了从关联表 sessionloads中 删除一个条目,我执行以下代码: 但是,启动后,此代码将保持不变。 删除关联的正确方法是什么? 问题答案: 您需要更新和之间的链接的两端: 实际上,许多开发人员使用防御性方

  • 比如我们要关联用户和角色之间的关系,就要用到多对多。多对多需要一张中间表来做关联。 定义 多对多关联会用到的注解: @ManyToMany、@JoinFromMiddle、@JoinToMiddle、@AutoSelect、@AutoInsert、@AutoUpdate、@AutoSave、@AutoDelete 如 imi-demo 中代码所示,类定义了一个$userRole属性和$role属性