java org.hibernate.MappingException:外键 XXX 的列数必须与引用的主键 YYY 的列数相同

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14172401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:20:52  来源:igfitidea点击:

org.hibernate.MappingException: Foreign key XXX must have same number of columns as the referenced primary key YYY

javahibernatejpaormhibernate-mapping

提问by Alexander Tumin

Having a following SQL table:

具有以下 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)
);

and Following JPA-Annotated POJOs:

并遵循 JPA 注释的 POJO:

RatingId.java:

评级Id.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:

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

后.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
}

I am getting

我正进入(状态

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])

on servlet container initialization stage.

在 servlet 容器初始化阶段。

What does it mean (What are Foreign Keys in this mappings? What are Primary Keys? Which annotations are marking what?) and how it could be fixed?

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

回答by JB Nizet

This mapping doesn't make much sense. You have an entity UserPostRating, mapped to the users_posts_ratings_map, and having a ManyToOneassociation with the entity Post.

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

And in Post, you have a set of UserPostRating, but you map it as a second association, and make it a ManyToMany. It isn't a ManyToMany. It's a OneToMany, since the other side is a ManyToOne. And since the bidirectional association is already mapped in UserPostRating, you can't map it a second time in Post. So the code should be:

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

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

回答by Andremoniy

According to the error message I suspect, that you have to move the definition of

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

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

from the class UserPostRatingto the class RatingId.

从班级UserPostRating到班级RatingId

回答by Manmaya Champatiray

The Mapping is correct, since it is a many to many mapping so its mapping will result to new table. So you should not refer to existing entity table, rather you should provide any other name whose mapping/entity name does not exist. Below is your example :

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

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

Change the name from"users_posts_ratings_map"to any other name like users_posts_ratings_map1or users_posts_ratings_map_item.

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