Java 三向hibernate ORM映射-如何?

Java 三向hibernate ORM映射-如何?,java,sql,hibernate,orm,hibernate-mapping,Java,Sql,Hibernate,Orm,Hibernate Mapping,我有三个SQL表: create table users ( id serial primary key, name text not null unique ); create table posts ( id serial primary key, data text not null, authorId integer not null references users (id) ); create table ratings ( id serial prima

我有三个SQL表:

create table users (
  id serial primary key,
  name text not null unique
);

create table posts (
  id serial primary key,
  data text not null,
  authorId integer not null references users (id)
);

create table ratings (
  id serial primary key,
  name text not null unique
);
一篇文章只能有一个作者,因此
用户
文章
关系已经以正常形式建立(如果我错了,请纠正我)

评级是预定义的常量,如“坏”、“好”或“棒”,在实际情况中,还有额外的数据作为评级值、描述或其他字段,我在这里省略了这些字段,以简洁明了

接下来,我想将评级与用户和帖子联系起来。每个帖子可以由每个用户进行一次评分,也可以由多个用户进行评分。我得出了以下关系:

create table posts_ratings_users_map (
  postId integer not null references posts (id),
  ratingId integer not null references ratings (id),
  userId integer not null references users (id),
  primary key (postId, ratingId, userId)
);
但问题是:我找不到一种方法将其集成到Hibernate ORM映射中,以获取每个帖子列表(或集合,或任何其他集合)的成对(用户、评级)

下面是我现在如何尝试绘制它们的地图:

User.java:

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

    @Column(nullable = false)
    private String name;

    @OneToMany
    @JoinColumn(name = "authorId")
    private Set<Post> posts = new HashSet<>();

    // ...
    // getters and setters
    // ...
}
@实体(name=“users”)
公共类用户{
@身份证
@列(nullable=false)
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
@列(nullable=false)
私有字符串名称;
@独身癖
@JoinColumn(name=“authord”)
private Set posts=new HashSet();
// ...
//接球手和接球手
// ...
}
Rating.java:

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

    @Column(nullable = false)
    private String name;

    @ManyToMany(mappedBy = "ratings")
    private Set<Post> posts = new HashSet<>();

    // ...
    // getters and setters
    // ...
}
@实体(name=“评级”)
公共等级评定{
@身份证
@列(nullable=false)
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
@列(nullable=false)
私有字符串名称;
@许多(mappedBy=“评级”)
private Set posts=new HashSet();
// ...
//接球手和接球手
// ...
}
Post.java:

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

    @Column(nullable = false)
    private String data;

    @ManyToOne
    @JoinColumn(name = "authorId")
    private User author;

    @ManyToMany
    @JoinTable(
            name = "posts_ratings_users_map",
            joinColumns = { @JoinColumn(name = "ratingId") },
            inverseJoinColumns = { @JoinColumn(name = "postId") }
    )
    private Set<Rating> ratings = new HashSet<>(); // here is the problem. i can relate ratings to this post, but how
                                                   // do i relate them with users which assigned their ratings to this
                                                   // post ?


    // ...
    // getters and setters
    // ...
}
@Entity(name=“posts”)
公营职位{
@身份证
@列(nullable=false)
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
@列(nullable=false)
私有字符串数据;
@许多酮
@JoinColumn(name=“authord”)
私人用户作者;
@许多
@可接合(
name=“posts\u ratings\u users\u map”,
joinColumns={@JoinColumn(name=“ratingId”)},
inverseJoinColumns={@JoinColumn(name=“postId”)}
)
private Set ratings=new HashSet();//问题出在这里。我可以将评级与这篇文章联系起来,但如何联系呢
//我是否将它们与为其分配评级的用户关联
//邮寄?
// ...
//接球手和接球手
// ...
}
为了将评分和用户对列表与每个帖子联系起来,需要更改哪些内容

UPD1


明显错误:posts\u ratings\u users\u map的主键应该是
(postId,userId)
(不包括
ratingId
),否则同一用户可以在同一帖子上放置不同的评级。

将用户包括在评级类中

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

@Column(nullable = false)
private String name;

@ManyToMany(mappedBy = "ratings")
private Set<Post> posts = new HashSet<>();

@Onetoone
private User ratedBy;

// ...
// getters and setters
// ...
}
@实体(name=“评级”)
公共等级评定{
@身份证
@列(nullable=false)
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
@列(nullable=false)
私有字符串名称;
@许多(mappedBy=“评级”)
private Set posts=new HashSet();
@奥内托内
私人用户费率;
// ...
//接球手和接球手
// ...
}

也许可以稍微更改一下您的型号

用户有你说已经定义的帖子

为什么不创建一个新的实体“UserRating”

@Entity(name = "user_ratings")
public class UserRating {
    @Id
    @Column(nullable = false)
    @GeneratedValue
    private Integer id;

    @ManyToOne(nullable = false)
    @JoinColumn(name = "ratingId")
    private Rating rating;

    @ManyToOne(nullable = false)
    @JoinColumn(name = "authorId")
    private User ratedBy;
 }
现在,在您的
Post
上,不再是
manytomy
拥有
OneToMany
关系。使用评级id和用户id作为
UserRating
类的键更为理想,但在JPA/Hibernate中这不容易建模,这使得它非常复杂。如果您感兴趣,请看一下这些问题


我说你需要另一张桌子
user\u post\u rating
带有user\u id、post\u id和rating\u id列,所有列都作为组合主键。此表将存储用户对哪个post给出哪个评级的数据。评级表只是一组预定义的评级,如好、坏、优秀。您需要一个带有rating_id、post_id和user_id的映射表来存储真实信息。@shazinltc抱歉,但不幸的是,这并没有那么简单。只是因为这个注释不会提供一个提示,在哪个表中执行一对一(同样,它是区分大小写的,
@OneToOne
)关系,也不会提供哪个列,也不会提供如何执行的提示。我觉得这不是很直观。我也会这样做。通过引入用户评级,您会得到一些非常自然可以理解的东西——即使是经理也会理解:-)