JPA与具有索引列的连接表的多对多关联创建新的主键

时间:2014-10-18 06:34:50

标签: hibernate jpa

目前我们在项目中遇到了这个关键问题,并且不确定如何配置JPA以满足我们的预期需求

我们的数据库中有5个表,其关系如下

A
Id

B
Id

C
Id

A_B
Id A_Id B_Id

D
Id A_B_Id C_Id

恩典A

@Entity
Class A{

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "A_B", joinColumns = @JoinColumn(name = "A_Id", referencedColumnName = "Id"), inverseJoinColumns = @JoinColumn(name = "B_Id", referencedColumnName = "Id"))
    private List<B> bList;
}

现在,当我尝试保存实体A时,由于将B存储在List中(我们无法更改为Set),它首先从A_B中删除所有记录然后重新插入。这是不可取的,因为D引用了A_B Id,所以根据下面的文章,我在A_B中添加了一个索引列,它解决了保存问题

http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

现在我的A_B看起来像

A_B
Id A-Id B_Id idx

和实体A为

@Entity
    Class A{

        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "A_B", joinColumns = @JoinColumn(name = "A_Id", referencedColumnName = "Id"), inverseJoinColumns = @JoinColumn(name = "B_Id", referencedColumnName = "Id"))
        @OrderColumn(name = "idx")
        private List<B> bList;
    }

执行此更改后,我无法部署代码,因为JPA正在为实体C抛出异常

Caused by: org.hibernate.MappingException: Foreign key (FK76F831D84C8F0D59:D[A_B_Id])) must have same number of columns as the referenced primary key (A_B[A_Id,idx])
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:110)
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:93)
    at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1714)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1637)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1355)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
    ... 45 more

Entity C is

    @Entity
    class C{

    @ManyToMany
        @JoinTable(name = "D", joinColumns = @JoinColumn(name = "C_Id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "A_B_Id", referencedColumnName = "id"))
        private List<A_B> a_bList;
    }

所以在这里我们无能为力如何在没有删除的情况下保存A并保持D关系不变。任何帮助将不胜感激

由于

1 个答案:

答案 0 :(得分:0)

以来,A和B之间没有ManyToMany
  • A_B表被映射为实体,因此它也不能映射为连接表
  • A_B表有一个ID列,如果映射为连接表,它将永远不会被Hibernate填充

出于同样的原因,C和A_B之间的关联也是如此。

你应该拥有的是

  • A有一个带有AB的OneToMany
  • B有一个带有AB的OneToMany
  • D有一个带有AB
  • 的ManyToOne
  • D有一个带有C
  • 的ManyToOne

当然,所有这些关联也可以映射到另一个方向。