dumb_terminal
dumb_terminal

Reputation: 1825

JPA ManyToMany unidirectional relationship

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 ?

Upvotes: 15

Views: 22782

Answers (3)

sunitkatkar
sunitkatkar

Reputation: 2086

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.

Upvotes: 1

cнŝdk
cнŝdk

Reputation: 32145

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

Upvotes: 11

Guillaume
Guillaume

Reputation: 494

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...

Upvotes: 9

Related Questions