Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join more than two tables using Annotations in Spring Data JPA

I've three entities: A, B and C, and the relation between them is as following:

class A{
    @ManyToMany
    List<B> bs;
    //other attributes and getter setters
}

class B{

    @ManyToMany
    List<C> cs;
    //other attributes and getter setters
}

class C{
    //other attributes and getter setters
}

But from my current entity classes, I can make relation between any 2 tables using @JoinTable. But what I want is to save relation between all 3 entities in a separate table, having primary keys of these entities as columns. (Foreign keys)

If we assume entities B and C are already saved (inserted) into database and I insert new entity of A as following:

A:{
  "A_id": 1
  B:[
    "B_id": 1
    {
      C:[
          {"C_id": 1}, {"C_id": 2}
        ]
    }, 
    {
      "B_id": 2
      C:[
          {"C_id": 2}
        ]
     }
  ]
}

Then A should be saved in it's table and the relations should be listed in a separate table as following:

A_id    B_id    C_id
=====================
 1       1       1
 1       1       2
 1       2       2

One of the related question I've seen here. But I think my scenario is different as I've many to many relations between all the entities A, B and C.

I'm not asking for full code. Any approach or exact reference will be fine as long as it solves the purpose. Thanks

EDIT:

I've tried implementing the separate relation table as mentioned in the answer. But the problem with this approach is that, when I remove a row from the relation table, It also removes the entry from the join table of B and C. (Affects the previous relation of entities B and C)

Also while updating updating the row, it changes (performs insert) into the join table of entity B and C. Which is not expected behavior. I want this table for just storing the relation between the entities and not for changing previous relations between those entities.

Following is my new relation table:

@Entity
@Table(name = "relation_table")
public class RelationEntity {

    @Id
    @Column(name = "pk_relation_id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer relatoinId;

    @OneToOne
    @JoinColumn(name = "a_id")
    private A a;

    @OneToOne
    @JoinColumn(name = "b_id")
    private B b;

    @OneToOne
    @JoinColumn(name = "c_id")
    private C c;

    //getter and setters
}
like image 384
Kaushal28 Avatar asked Apr 20 '18 12:04

Kaushal28


People also ask

How do you join two tables in spring?

Here is an attempt: @Entity @Table(name = "Release_date_type") public class ReleaseDateType { @Id @GeneratedValue(strategy=GenerationType. TABLE) private Integer release_date_type_id; // ... @Column(nullable = true) private Integer media_Id; // with getters and setters... }

How do I join two entities in JPA?

The only way to join two unrelated entities with JPA 2.1 and Hibernate versions older than 5.1, is to create a cross join and reduce the cartesian product in the WHERE statement. This is harder to read and does not support outer joins. Hibernate 5.1 introduced explicit joins on unrelated entities.

Which annotation is used to link two tables with a relation table?

The @JoinTable is used to define the join/link table. In this case, it is Employee_Project. The @JoinColumn annotation is used to specify the join/linking column with the main table. Here, the join column is employee_id and project_id is the inverse join column since Project is on the inverse side of the relationship.


1 Answers

If you want to keep the relation in separate table then you can simply do something like this to save primary keys

@Entity
@Table(name = "relation_bridge")
public class RelationBridge {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "a")
    private A a;

    @ManyToOne
    @JoinColumn(name = "b")
    private B b;

    @ManyToOne
    @JoinColumn(name = "c")
    private C c;

    //getters & setters
}

EDIT

When I remove a row from the relation table, It also removes the entry >from the join table of B and C. (Affects the previous relation of >entities B and C)

The above solution should not delete the entries in a parent table unless explicitly defined. However you may be using other mappings in your other classes so this behavior can be controlled by applying Cascading in your mappings.

A Beginner's Guide to JPA and Hibernate Cascade Types

Good read for beginners

like image 73
UsamaAmjad Avatar answered Oct 10 '22 02:10

UsamaAmjad