JPA ManyToMany unidirectional relationship
Asked Answered
E

3

15

Lets say we have two Entities, Entity Node and Entity Cluster. A Cluster has many Nodes. A Node can belong to multiple Cluster. So in Cluster there is a @ManyToMany annotation. However Node is unaware of any Cluster it belongs to (intentional).

When I delete a Cluster I want to keep all the Nodes (in future I may add those Nodes to another Cluster) it had. So I don't need Cascade.DELETE. But If I delete a Node, all the Cluster it belonged to should be updated (the Node will be removed from them).

What is the best way to handle this using JPA ?

Efficiency answered 12/5, 2016 at 11:38 Comment(0)
S
9

That's because Node is unaware of any Cluster it belongs to.

If you use bidirectionnal relationship, you have to choose which side will update links between Node and Cluster. Choose the entity the most important on your business point of view... To save the association, you need to save the owning entity of the relationship.

If you don't want bidirectionnal relationship, you need to remove the Node from all Cluster.nodes before deleting the Node itself...

Silvester answered 12/5, 2016 at 12:52 Comment(1)
Yeah had to made it bi-directional.Efficiency
P
11

In fact in a unidirectional relationship, you can specify the holder entity of the relationship using joinColumn="clusterId" property in the @ManyToMany annotation in the `Cluster class.

This is how should be your code:

@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
}

For further reading please take a look at :

Hibernate @ManyToMany Unidirectional and Bidirectional

Pear answered 12/5, 2016 at 14:54 Comment(2)
I really want to read the docs before come to Stack, but sometimes is somehow hard to find. So I love to find such a comment that make it easy to understand and brings the official docs or good articles. Thank you!Duralumin
@NikolasFreitasMrNik You are welcome, yes indeed it's better and surely easier to find a simple answer that points out the features and brings a link to the docs's sections that summarizes it. Enjoy :)Instrumentalist
S
9

That's because Node is unaware of any Cluster it belongs to.

If you use bidirectionnal relationship, you have to choose which side will update links between Node and Cluster. Choose the entity the most important on your business point of view... To save the association, you need to save the owning entity of the relationship.

If you don't want bidirectionnal relationship, you need to remove the Node from all Cluster.nodes before deleting the Node itself...

Silvester answered 12/5, 2016 at 12:52 Comment(1)
Yeah had to made it bi-directional.Efficiency
B
1

I am way too late to this thread, but I had similar issues with Spring Boot 2.4. I had 2 ManyToMany unidirectional relationships from the parent entity to the same child entity.

I would end up getting 1 or 2 less entity relationships saved in the join table.

Then I realized that I had missed out on the most basic thing for an entity/pojo - overriding the hashCode and equals method!

Once I added those, Hibernate started to behave as expected.

Blim answered 15/6, 2021 at 18:38 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.