Hibernate不会将OneToMany中的父实体删除为复合键,而不是删除键和实体

时间:2017-11-12 17:16:04

标签: hibernate jpa

我有两个主要实体:ClientBundle。它们具有双向ManyToMany关系,可以按预期工作。例子:

  1. 客户端有几个捆绑包。我删除了客户端。所有捆绑实体都会在删除该客户端时更新,但捆绑实体仍然存在。
  2. 我更新了一个客户端并从其Set<Bundle>中删除了一个包。同一个捆绑包将更新其Set<Client>客户端。捆绑实体将保留。
  3. 所有这些都是双向的。

    ClientBundle都具有OneToMany关系,作为复合键,具有实体ClientBundleApproval。它还有一个枚举(批准,拒绝,待定)。

    我的问题是:假设我配置了多个实体。客户有几个捆绑包,有几个批准待定。当我尝试删除客户端时,如果在ClientBundleApproval中存在包含复合键的行,将不会删除

    我的预期结果是,ClientBundleApproval中包含该客户端ID的所有行都将被删除,并且所有捆绑包都会删除其相关批准的集合,并更新客户端(基本上是级联删除,但仅限于复合键表而不是其他实体)。添加级联删除会导致删除客户端以删除复合键,还会删除捆绑包(这不是所需行为)。

    我需要帮助弄清楚我的配置是否有问题,或者是不可能的。我假设我可能首先删除复合键行,但我需要保持处理这些实体的服务逻辑分开。 (例如,在ClientService中不必注入其他实体&#39; JpaRepository<T, ID>

    实施说明:我正在使用Spring JPA,因此对于每个实体我都有一个扩展Spring JpaRepository<T, ID>的接口,我将其注入服务类并使用它进行CRUD操作而不是EntityManager

    我尝试从OneToMany中移除mappedBy,不同类型的级联(在关系声明和使用@Cascade中),有和没有孤儿删除。没有什么我能想到的。

    实体和图表:

    客户(我删除了一些样板)

    @Entity
    @Table(name = "client_details")
    public class Client implements Serializable {
    
        @JoinTable(
                name = "client_bundle",
                joinColumns =  { @JoinColumn(name = "client_id") },
                inverseJoinColumns = { @JoinColumn(name = "bundleName") }
        )
        @Column(name = "bundles")
        @ManyToMany(fetch = FetchType.EAGER /* all types of cascade except delete */)
        private Set<Bundle> clientBundles;
    
        @OneToMany(mappedBy = "client", fetch = FetchType.EAGER, orphanRemoval = true /* all types of cascade except delete */)
        private List<ClientBundleApproval> approvals;
    
    }
    

    捆绑

    @Entity
    @Table(name = "bundle")
    public class Bundle implements Serializable {
    
        @ManyToMany(mappedBy="clientBundles", fetch = FetchType.EAGER /* all types of cascade except delete */)
        private Set<Client> clients;
    
        @OneToMany(mappedBy = "bundle", fetch = FetchType.EAGER, orphanRemoval = true /* all types of cascade except delete */)
        private List<ClientBundleApproval> approvals;
    
    }
    

    ClientBundleApproval

    @Entity
    @Table(name = "client_bundle_approval")
    public class ClientBundleApproval implements Serializable {
    
        @EmbeddedId
        private ClientBundleKey clientBundleKey;
    
        @ManyToOne(fetch = FetchType.EAGER /* all types of cascade except delete */)
        @JoinColumn(name = "client", referencedColumnName = "id")
        @MapsId("clientId")
        private Client client;
    
        @ManyToOne(fetch = FetchType.EAGER /* all types of cascade except delete */)
        @JoinColumn(name = "bundle", referencedColumnName = "id")
        @MapsId("bundleId")
        private Bundle bundle;
    
        @Enumerated(EnumType.STRING)
        private ClientBundleApprovalStatus approvalStatus;
    
    }
    

    ClientBundleKey

    @Embeddable
    public class ClientBundleKey implements Serializable{
        private String clientId;
        private String bundleId;
    }
    

    diagram

0 个答案:

没有答案