我试图使用Spring Data JPA从多对多的关系中删除条目 . 其中一个模型是关系的所有者,我需要删除非所有者实体的条目 . 这些是模型:
Workflow entity
@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...
}
DataUpload entity
@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...
}
DataUpload repository
@Repository
public interface DataUploadsRepository extends JpaRepository<DataUpload, UUID> {
@Transactional
void delete(DataUpload dataUpload);
Optional<DataUpload> findByDataUploadId(UUID dataUploadId);
}
要删除数据上传,我试图执行存储库的几个查询方法:
First version
dataUploadsRepository.deleteAll(workflow.getDataUploads());
Second version
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
(关联表)中删除?
我将不胜感激任何帮助 .
2 回答
我找到了解决这个问题的方法 . 基本上,两个实体(在我的情况下)都需要是关系的所有者,并且必须首先删除关联表中的数据 .
Workflow entity (关系所有者)
DataUpload entity (关系所有者)
请注意,Workflow将ALL作为级联类型,因为(基于我需要的逻辑),我希望Spring Data JPA在修改工作流时删除,合并,刷新,保持和分离DataUpload . 另一方面,DataUpload没有级联类型,因为我不希望由于DataUploads删除而影响工作流实例(和记录) .
为了成功删除DataUploads,应首先删除关联数据:
dataUploadIterator.remove()
从关联表(workflow_data
)中删除记录,然后使用dataUploadRepository.delete(dataUploadEntry);
删除DataUpload .已经有一段时间了,因为我必须修复这些映射,所以我不会给你一个代码修复,而是可能给你另一个视角 .
首先是一些问题,你真的需要多对多吗?是否有任何这些实体存在而没有另一个实体? DataUpload本身可以存在吗?
在这些映射中,您应该取消分配双方的关系,并记住您始终可以执行查询以删除实际值(对实体和中间人的查询)
我希望有几个链接对您有用,它们解释了映射的最佳实践和不同的删除方法 .
Delete Many,Delete Many to Many,Best way to use many to many.