Java Spring数据JPA-删除多对多条目

Java Spring数据JPA-删除多对多条目,java,spring,spring-data-jpa,many-to-many,Java,Spring,Spring Data Jpa,Many To Many,我试图使用SpringDataJPA从多对多关系中删除条目。其中一个模型是关系的所有者,我需要删除非所有者实体的条目。这些是模型: 工作流实体 @Entity(name = "workflows") public class Workflow { @Id @Column(name = "workflow_id", updatable = false, nullable = false) @GeneratedValue(strategy = GenerationType.A

我试图使用SpringDataJPA从多对多关系中删除条目。其中一个模型是关系的所有者,我需要删除非所有者实体的条目。这些是模型:

工作流实体

@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数据JPA没有删除
数据上传
,也没有删除关联表
工作流\u数据的条目

如何告诉Spring数据从
数据上传
工作流数据
(关联表)中删除


我将非常感谢您的帮助。

我已经有一段时间没有修复此类映射了,所以我不会给您一个代码修复,而是可能给您另一个视角

首先是一些问题,比如,你真的需要多对多吗?这些实体中的任何一个存在而没有另一个存在,这有意义吗?数据上传本身可以存在吗

在这些映射中,您应该取消分配双方的关系,并记住,您始终可以执行查询以删除实际值(对实体和中间对象的查询)

我希望有几个链接对您有用,它们解释了映射的最佳实践和执行删除的不同方法


,我找到了这个问题的解决办法。基本上,两个实体(在我的例子中)都需要是关系的所有者,并且必须首先删除关联表中的数据

工作流实体(关系所有者)

@Entity(name=“工作流”)
公共类工作流{
@身份证
@列(name=“workflow\u id”,updateable=false,nullable=false)
@GeneratedValue(策略=GenerationType.AUTO)
私有UUID-workflowId;
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name=“工作流\数据”,
joinColumns=@JoinColumn(name=“workflow\u id”,referencedColumnName=“workflow\u id”),
inverseJoinColumns=@JoinColumn(name=“data\u upload\u id”,referencedColumnName=“data\u upload\u id”))
private Set dataUploads=new HashSet();
//二传手和接球手。。。
}
数据上传实体(关系所有者)

@Entity(name=“数据上传”)
公共类数据上传{
@身份证
@列(name=“数据上传id”)
专用UUID数据上传ID;
@许多
@JoinTable(name=“工作流\数据”,
joinColumns=@JoinColumn(name=“data\u upload\u id”,referencedColumnName=“data\u upload\u id”),
inverseJoinColumns=@JoinColumn(name=“workflow\u id”,referencedColumnName=“workflow\u id”))
私有集工作流=新HashSet();
//二传手和接球手。。。
}
请注意,工作流具有ALL as cascade类型,因为(根据我需要的逻辑),我希望Spring Data JPA在修改工作流时删除、合并、刷新、持久化和分离数据上传。另一方面,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);
    }
}
public void deleteDataUploads(工作流){
for(迭代器dataUploadIterator=workflow.getDataUploads().Iterator();dataUploadIterator.hasNext();){
DataUpload dataUploadEntry=dataUploadIterator.next();
dataUploadIterator.remove();
dataUploadsRepository.delete(dataUploadEntry);
}
}

dataUploadIterator.remove()
从关联表(
workflow\u data
)中删除记录,然后使用
dataUploadRepository.delete(dataUploadEntry)删除数据上载

这些都是好问题。我需要两个实体都有这种关系。我找到了这个问题的解决方案,正如您所说,我应该在删除所需记录之前取消分配关系。我将分享我的发现。谢谢你的回答!
@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...
}
public void deleteDataUploads(Workflow workflow) {
    for (Iterator<DataUpload> dataUploadIterator = workflow.getDataUploads().iterator(); dataUploadIterator.hasNext();) {
        DataUpload dataUploadEntry = dataUploadIterator.next();
        dataUploadIterator.remove();

        dataUploadsRepository.delete(dataUploadEntry);
    }
}