JPA 多对多单向关系

JPA ManyToMany unidirectional relationship

假设我们有两个实体,实体 Node 和实体 Cluster。 一个 Cluster 有很多 Node。一个 Node 可以属于多个 Cluster。所以在 Cluster 中有一个 @ManyToMany 注释。然而 Node 不知道它属于任何 Cluster(故意)。

当我删除 Cluster 时,我想保留它拥有的所有 Node(将来我可能会将那些 Node 添加到另一个 Cluster)。所以我不需要Cascade.DELETE。但是如果我删除一个 Node,它所属的所有 Cluster 都应该更新(Node 将从它们中删除)。

使用 JPA 处理此问题的最佳方法是什么?

那是因为 Node 不知道它属于哪个 Cluster

如果您使用双向关系,您必须选择哪一方将更新 NodeCluster 之间的链接。从您的业务角度选择最重要的实体...要保存关联,您需要保存关系的拥有实体。

如果您不想要双向关系,您需要在删除 Node 本身之前从所有 Cluster.nodes 中删除 Node...

实际上在单向关系中,可以使用`Cluster class中的@ManyToMany注解中的joinColumn="clusterId" 属性来指定关系的持有者实体。

你的代码应该是这样的:

@Entity
@Table(name="Cluster")
public class Cluster {

    //Id and properties

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name="Cluster_Nodes", 
                joinColumns={@JoinColumn(name="clusterId")}, 
                inverseJoinColumns={@JoinColumn(name="nodeId")})
    private Set<Node> nodes = new HashSet<Node>();

    // Getter and Setter methods
}

如需进一步阅读,请查看:

Hibernate @ManyToMany Unidirectional and Bidirectional

我来得太晚了,但我在 Spring Boot 2.4 中遇到了类似的问题。我有 2 个从父实体到同一个子实体的 ManyToMany 单向关系。

我最终会在连接中保存 1 或 2 个较少的实体关系 table。

然后我意识到我错过了 entity/pojo 最基本的东西 - 重写 hashCode 和 equals 方法!

添加这些后,Hibernate 开始按预期运行。