JPA - @ManyToMany对同一外键

时间:2018-04-09 09:11:28

标签: java jpa

我有3个这样的实体:

@Entity
public class A {

    @Id
    private String id;

}

@Entity
@IdClass(B.BPK.class)
public class B {

    @Id
    private String id;
    @Id
    @ManyToOne
    private A a;

}

@Entity
public class C {

    @Id
    private int refOne;
    @Id
    private int refTwo;    
    @Id
    private A a;
    @ManyToMany
    private Set<B> bs;

}

我有一个关于为实体C的@ManyToMany关系生成的表的问题。生成了5列:refOne,refTwo,a_id,b_id,b_a_id。

正如您所看到的,a_id和b_a_id是同一列上的外键,在我的模型中,a_id与b_a_id不同。

是否有不重复列的解决方案?

修改

我坚持这一点,A是C的id的一部分,C中的bs可能是空的。

我想到了几个解决方案,但没有一个真正令人满意:

  • 使用使用b_id和a_id恢复bs实体的转换器
  • 我尝试使用@JoinTable来管理列:

JoinTable方法:

@JoinTable(name = "bs", joinColumns = {
            @JoinColumn(name = "refOne", referencedColumnName = "refOne"),
            @JoinColumn(name = "refTwo", referencedColumnName = "refTwo"),
            @JoinColumn(name = "a_id", referencedColumnName = "a_id")
    }, inverseJoinColumns = {
            @JoinColumn(name = "b_id", referencedColumnName = "b_id"),
            @JoinColumn(name = "b_a_id", referencedColumnName = "b_a_id", insertable = false, updatable = false)

但我面对这些问题Mixing insertable and non insertable columns in a property is not allowed or参数索引超出范围`         })

2 个答案:

答案 0 :(得分:0)

由于C已经引用了A,你可以获取A.bs,而不必在C中声明一个b的集合。但是,你需要在实体A中有一个Set<B>

当然,除非您无法更改映射...

答案 1 :(得分:0)

您可以使用引用private A a;的{​​{1}}注释@JoinColumn。还有其他注释可以让您进一步配置映射。然而,使2个FK列包含相同值没有问题。

另外,您应该始终手动创建表格。不要让它在生产中生成。

有关详细信息,请阅读docs。也许您必须搜索更具体的问题,但资源就在那里