如何正确级联从集合中删除实体?

时间:2015-02-06 16:29:13

标签: java hibernate jpa orm

我试图在两个带有连接表的Hibernate实体之间实现多对一关系,但是我遇到了从“一个”方面集合中删除实体的问题。

我在以下代码片段中省略了简单的getter / setter。

代码

“one”side实体代表数据库中的FTP_SERVER:

@Entity
@Table(name = "ftp_server")
public class FtpServerEntity {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToMany(mappedBy = "ftpServer", cascade = CascadeType.ALL)
  @Fetch(FetchMode.JOIN)
  private List<SmtpRecipientEntity> smtpRecipients;

}

“很多”(并且拥有)的旁边实体代表一个SMTP_RECIPIENT:

@Entity
@Table(name = "smtp_recipient")
public class SmtpRecipientEntity {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ManyToOne(cascade = CascadeType.ALL)
  @JoinTable(
        name = "ftp_error_recipient",
        joinColumns = @JoinColumn(name = "smtp_recipient_id"),
        inverseJoinColumns = @JoinColumn(name = "ftp_server_id")
  )
  private FtpServerEntity ftpServer;

}

连接表只有以下外键:

FOREIGN KEY (smtp_recipient_id) REFERENCES smtp_recipient (id)
FOREIGN KEY (ftp_server_id) REFERENCES ftp_server (id)

问题

只需将SmtpRecipientEntity添加到FtpServerEntity#smtpRecipients集合就可以正常工作,并在更新时在连接表中创建一行。

但是,当我修改集合,然后保留FtpServerEntity时,删除的记录不会从连接表中删除。

// This has three SmtpRecipientEntity objects in its collection
FtpServerEntity ftpServer = ftpServerDao.get(ftpServerId);

List<SmtpRecipientEntity> recipients = ftpServer.getSmtpRecipients();
recipients.clear();
recipients.add(smtpRecipientDao.get(smtpRecipientId));

// The collection now has only one different entity in it
ftpServerDao.save(ftpServer);  // performs a merge and flush

此代码将为添加到集合的实体的连接表添加新记录,但不会删除不再包含在集合中的记录的记录。我可以通过几种不同的方式手动执行此操作,但这感觉就像Hibernate应该能够处理的那样。

关于我失踪的任何想法?感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

除了orphanRemoval = true之外,请尝试添加Cascade.ALL,以便在不再向所有者引用子元素时将其删除。