【问题标题】:JPA mapping: Foreign key must have same number of columns in the referenced primary keyJPA 映射:外键在引用的主键中必须具有相同数量的列
【发布时间】:2014-07-27 19:09:22
【问题描述】:

我正在使用 JPA 2.0 和 Hibernate 4.1.0.Final。我无法弄清楚如何映射几个实体。我有一个 Group 和一个 GroupMember 类,但是下面的映射......

@Entity
@Table(name = "group")
public class Group    
{
    @Id
    @NotNull
    @GeneratedValue(generator = "uuid-strategy")
    @Column(name = "ID")
    private String id;
    …

    @ManyToMany
    @ElementCollection
    @CollectionTable(name="group_member", joinColumns=@JoinColumn(name="GROUP_ID"))
    private Set<GroupMember> members;




@Entity
@Table(name = "group_member")
public class GroupMember
{

    @Id
    @NotNull
    @GeneratedValue(generator = "uuid-strategy")
    @Column(name = "ID")
    private String id;
    …

    @ManyToOne
    @JoinColumn(name = "GROUP_ID", nullable = false, updatable = true)
    private Group group;

导致这个异常......

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:287)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
    ... 38 more
Caused by: org.hibernate.MappingException: Foreign key (FK4719AC489E4DD84:group_member [members_ID])) must have same number of columns as the referenced primary key (group_member [GROUP_ID,members_ID])
    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:1704)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1627)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1362)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1727)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:88)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)

如何将我的 GroupMembers 字段映射到我的 Group 类?

    ... 44 more

【问题讨论】:

    标签: hibernate jpa mapping jpa-2.0


    【解决方案1】:

    问题是您的一侧有@OneToMany,另一侧有@ManyToMany。此外,@ElementCollection 和 @CollectionTable 在这种情况下是错误的注释,因为您正在处理实体集合而不是 Embeddables:

    http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection

    如果模型是这样的,一个组可以有多个成员,一个成员可以属于多个组,那么您有两种选择。您可以使用@ManyToMany Group Member(并使用@JoinTable 来定义联接表),或者您可以为联接定义一个中间实体并将关系映射为@OneToMany。

    后者是推荐的方法,因为它允许您存储有关关系的额外信息:例如,在这种情况下,您可以在 GroupMember 上定义一个额外的字段来存储成员加入组的日期。

    @Entity
    @Table(name = "group")
    public class Group    
    {
        @Id
        @NotNull
        @GeneratedValue(generator = "uuid-strategy")
        @Column(name = "ID")
        private String id;
        …
    
        @OneToMany(mappedBy = "group")
        private Set<GroupMember> members;
    }
    
    @Entity
    @Table(name = "member")
    public class Member    
    {
        @Id
        @NotNull
        @GeneratedValue(generator = "uuid-strategy")
        @Column(name = "ID")
        private String id;
        …
    
        @OneToMany(mappedBy = "member")
        private Set<GroupMember> groups;
    }
    
    @Entity
    @Table(name = "group_member")
    public class GroupMember
    {
    
        @Id
        @NotNull
        @GeneratedValue(generator = "uuid-strategy")
        @Column(name = "ID")
        private String id;
        …
    
        @ManyToOne
        @JoinColumn(name = "GROUP_ID", nullable = false, updatable = true)
        private Group group;
    
        @ManyToOne
        @JoinColumn(name = "MEMBER_ID", nullable = false, updatable = true)
        private Member member;
    }
    

    【讨论】:

    • 花了太多时间才找到这个。很好的建议。我同意这种做法,您的示例效果很好。
    • 如果我们想通过Member 对象返回Set&lt;Group&gt; 会是什么样子?我正在尝试this example,但我一直在处理外键问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 2019-11-18
    • 2016-08-22
    • 2019-07-30
    • 2013-01-08
    • 1970-01-01
    相关资源
    最近更新 更多