在Spring Data JPA中使用Annotations连接两个以上的表

时间:2022-09-21 22:52:48

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

我有三个实体:A,B和C,它们之间的关系如下:

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)

但是从我当前的实体类中,我可以使用@JoinTable在任何两个表之间建立关系。但我想要的是在一个单独的表中保存所有3个实体之间的关系,将这些实体的主键作为列。 (外键)

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

如果我们假设实体B和C已经保存(插入)到数据库中,我插入A的新实体,如下所示:

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应该保存在它的表中,关系应该列在一个单独的表中,如下所示:

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.

我在这里看到的一个相关问题。但我认为我的情况不同,因为我在所有实体A,B和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)

我已经尝试实现答案中提到的单独关系表。但是这种方法的问题在于,当我从关系表中删除一行时,它还会从B和C的连接表中删除该条目。(影响实体B和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.

此外,在更新更新行时,它会更改(执行插入)到实体B和C的连接表中。这不是预期的行为。我希望这个表只存储实体之间的关系,而不是改变这些实体之间的先前关系。

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
}

2 个解决方案

#1


7  

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)

当我从关系表中删除一行时,它还会从B和C的连接表中删除条目>。影响以前的>实体B和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.

除非明确定义,否则上述解决方案不应删除父表中的条目。但是,您可能在其他类中使用其他映射,因此可以通过在映射中应用Cascading来控制此行为。

A Beginner's Guide to JPA and Hibernate Cascade Types

JPA和Hibernate级联类型的初学者指南

Good read for beginners

适合初学者的好读物

#2


0  

And what about using your new class RelationEntity with A nullable. When you intent to remove the "new" relationship you update it putting null in A property. It's just a suggestion, forgive if you cannot make it this way.

那么使用你的新类RelationEntity和A nullable呢?当您打算删除“新”关系时,您更新它将null放在A属性中。这只是一个建议,原谅如果你不能这样做。

#1


7  

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)

当我从关系表中删除一行时,它还会从B和C的连接表中删除条目>。影响以前的>实体B和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.

除非明确定义,否则上述解决方案不应删除父表中的条目。但是,您可能在其他类中使用其他映射,因此可以通过在映射中应用Cascading来控制此行为。

A Beginner's Guide to JPA and Hibernate Cascade Types

JPA和Hibernate级联类型的初学者指南

Good read for beginners

适合初学者的好读物

#2


0  

And what about using your new class RelationEntity with A nullable. When you intent to remove the "new" relationship you update it putting null in A property. It's just a suggestion, forgive if you cannot make it this way.

那么使用你的新类RelationEntity和A nullable呢?当您打算删除“新”关系时,您更新它将null放在A属性中。这只是一个建议,原谅如果你不能这样做。