【问题标题】:org.hibernate.MappingException: Foreign key XXX must have same number of columns as the referenced primary key YYYorg.hibernate.MappingException:外键 XXX 的列数必须与引用的主键 YYY 相同
【发布时间】:2013-01-05 13:52:41
【问题描述】:

有如下 SQL 表:

create table users_posts_ratings_map (
  postId integer not null references posts (id),
  userId integer not null references users (id),
  ratingId integer not null references ratings (id),
  primary key (postId, userId)
);

并遵循 JPA 注释的 POJO:

RatingId.java:

@Embeddable
public class RatingId implements Serializable {
    @ManyToOne
    @JoinColumn(name = "userId")
    private User user;

    @ManyToOne
    @JoinColumn(name = "postId")
    private Post post;

    // getters and setters
}

UserPostRating.java:

@Entity(name = "users_posts_ratings_map")
public class UserPostRating {
    @EmbeddedId
    private RatingId userPost;

    @OneToOne
    @JoinColumn(name = "ratingId")
    private Rating rating;

    // getters and setters
}

Post.java

@Entity(name = "posts")
public class Post {
    @Id
    @Column(nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    // irrelevant fields

    @ManyToMany
    @JoinTable(
            name = "users_posts_ratings_map",
            joinColumns = { @JoinColumn(name = "ratingId") },
            inverseJoinColumns = { @JoinColumn(name = "postId"), @JoinColumn(name = "userId") }
    )
    private Set<UserPostRating> ratings = new HashSet<>();

    // getters and setters
}

我来了

org.hibernate.MappingException: Foreign key (FKB278E73083D94769:users_posts_ratings_map [postId,userId])) must have same number of columns as the referenced primary key (users_posts_ratings_map [ratingId,postId,userId])

在 servlet 容器初始化阶段。

这是什么意思(什么是映射中的外键?什么是主键?哪些注释标记了什么?)以及如何修复它?

【问题讨论】:

    标签: java hibernate jpa orm hibernate-mapping


    【解决方案1】:

    这种映射没有多大意义。您有一个实体UserPostRating,映射到users_posts_ratings_map,并与实体Post 有一个ManyToOne 关联。

    Post 中,您有一组UserPostRating,但您将其映射为第二个关联,并使其成为ManyToMany。这不是ManyToMany。这是OneToMany,因为另一边是ManyToOne。而且由于双向关联已经映射到UserPostRating,你不能在Post 中再次映射它。所以代码应该是:

    @OneToMany(mappedBy="userPost.post")
    private Set<UserPostRating> ratings = new HashSet<>();
    

    【讨论】:

      【解决方案2】:

      映射是正确的,因为它是多对多映射,所以它的映射将导致新表。因此,您不应引用现有实体表,而应提供任何其他名称,其映射/实体名称不存在。 以下是您的示例:

       @ManyToMany
          @JoinTable(
                  name = "users_posts_ratings_map",
                  joinColumns = { @JoinColumn(name = "ratingId") },
                  inverseJoinColumns = { @JoinColumn(name = "postId"), @JoinColumn(name = "userId") }
          )
          private Set<UserPostRating> ratings = new HashSet<>();
      

      将名称从 "users_posts_ratings_map" 更改为任何其他名称,例如users_posts_ratings_map1users_posts_ratings_map_item

      【讨论】:

        【解决方案3】:

        根据我怀疑的错误消息,您必须移动定义

        @OneToOne
        @JoinColumn(name = "ratingId")
        private Rating rating;
        

        UserPostRating 类到RatingId 类。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-18
          • 2019-11-18
          • 2019-07-30
          • 1970-01-01
          • 2013-01-08
          • 2016-08-22
          相关资源
          最近更新 更多