java - Spring Data JPA - 删除多对多条目
问题描述
我正在尝试使用 Spring Data JPA从多对多关系中删除条目。其中一个模型是关系的所有者,我需要删除非所有者实体的条目。这些是模型:
工作流实体
@Entity(name = "workflows")
public class Workflow {
@Id
@Column(name = "workflow_id", updatable = false, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID workflowId;
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(name = "workflow_data",
joinColumns = @JoinColumn(name = "workflow_id", referencedColumnName = "workflow_id"),
inverseJoinColumns = @JoinColumn(name = "data_upload_id", referencedColumnName = "data_upload_id"))
private Set<DataUpload> dataUploads = new HashSet<>();
// Setters and getters...
}
数据上传实体
@Entity(name = "data_uploads")
public class DataUpload {
@Id
@Column(name = "data_upload_id")
private UUID dataUploadId;
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "dataUploads")
private Set<Workflow> workflows = new HashSet<>();
// Setters and getters...
}
数据上传存储库
@Repository
public interface DataUploadsRepository extends JpaRepository<DataUpload, UUID> {
@Transactional
void delete(DataUpload dataUpload);
Optional<DataUpload> findByDataUploadId(UUID dataUploadId);
}
要删除数据上传,我正在尝试执行存储库的几个查询方法:
第一个版本
dataUploadsRepository.deleteAll(workflow.getDataUploads());
第二版
workflow.getDataUploads().stream()
.map(DataUpload::getDataUploadId)
.map(dataUploadsRepository::findByDataUploadId)
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(dataUploadsRepository::delete);
问题是 Spring Data JPA 没有删除DataUploads
关联表的条目workflow_data
。
如何告诉 Spring Data 从data_uploads
和workflow_data
(关联表)中删除?
我将不胜感激任何帮助。
解决方案
我找到了解决这个问题的方法。基本上,两个实体(在我的例子中)都需要是关系的所有者,并且必须首先删除关联表中的数据。
工作流实体(关系所有者)
@Entity(name = "workflows")
public class Workflow {
@Id
@Column(name = "workflow_id", updatable = false, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID workflowId;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(name = "workflow_data",
joinColumns = @JoinColumn(name = "workflow_id", referencedColumnName = "workflow_id"),
inverseJoinColumns = @JoinColumn(name = "data_upload_id", referencedColumnName = "data_upload_id"))
private Set<DataUpload> dataUploads = new HashSet<>();
// Setters and getters...
}
数据上传实体(关系所有者)
@Entity(name = "data_uploads")
public class DataUpload {
@Id
@Column(name = "data_upload_id")
private UUID dataUploadId;
@ManyToMany
@JoinTable(name = "workflow_data",
joinColumns = @JoinColumn(name = "data_upload_id", referencedColumnName = "data_upload_id"),
inverseJoinColumns = @JoinColumn(name = "workflow_id", referencedColumnName = "workflow_id"))
private Set<Workflow> workflows = new HashSet<>();
// Setters and getters...
}
请注意,Workflow具有ALL作为级联类型,因为(基于我需要的逻辑),我希望 Spring Data JPA在修改工作流时删除、合并、刷新、持久化和分离DataUpload 。另一方面,DataUpload没有级联类型,因为我不希望Workflow实例(和记录)由于DataUpload的删除而受到影响。
为了成功删除DataUpload,应首先删除关联数据:
public void deleteDataUploads(Workflow workflow) {
for (Iterator<DataUpload> dataUploadIterator = workflow.getDataUploads().iterator(); dataUploadIterator.hasNext();) {
DataUpload dataUploadEntry = dataUploadIterator.next();
dataUploadIterator.remove();
dataUploadsRepository.delete(dataUploadEntry);
}
}
dataUploadIterator.remove()
从关联表 ( workflow_data
) 中删除记录,然后使用删除DataUploaddataUploadRepository.delete(dataUploadEntry);
。
推荐阅读
- visual-c++ - 为什么在编译向量时VS2017和VS代码不同?
- android - 使用自定义源代码编译和更新 Flutter 的 Dart Dart 虚拟机
- html - ItextSharp 未封闭标签
- windows - 在 windows 上使用 exec.Command 进行 noverify
- excel - 如何将数据粘贴到 VBA 的特定行中?
- c - 无法打印函数返回的字符串
- python - Sphinx autodoc 找不到模块
- ios - 使用 IP 地址(xxx.xxx.xxx.xxx)而不是 URL 向 Mysql 发送数据
- azure-data-factory-2 - 自托管 IR 安全问题
- javascript - Vue切换不会恢复,只会切换一次