Having a following SQL table:
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:
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
}
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.
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?
This mapping doesn’t make much sense. You have an entity
UserPostRating, mapped to theusers_posts_ratings_map, and having aManyToOneassociation with the entityPost.And in
Post, you have a set ofUserPostRating, but you map it as a second association, and make it aManyToMany. It isn’t aManyToMany. It’s aOneToMany, since the other side is aManyToOne. And since the bidirectional association is already mapped inUserPostRating, you can’t map it a second time inPost. So the code should be: