三路休眠ORM映射 - 如何?

时间:2013-01-03 13:15:38

标签: 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 primary key,
  name text not null unique
);

一个帖子只能有一位作者,所以users< - > posts关系已经以正常形式建立(如果我错了,请纠正我)。

评级是预先定义的常量,例如“坏”,“好”或“真棒”,并且(在实际情况下)附加数据作为评级值,描述或其他字段,为简洁起见,我在此省略。

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

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

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

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

需要更改哪些内容才能将评级和用户对列表与每个帖子联系起来?

UPD1

明显错误:posts_ratings_users_map的PK应为(postId, userId)ratingId除外),否则同一位用户可以在同一帖子上添加不同的评分。

2 个答案:

答案 0 :(得分:2)

也许稍微改变一下你的模特。

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

为什么不创建一个新的实体'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而不是ManyToManyOneToMany关系。使用评级的id和用户作为UserRating类的键是更理想的,但这在JPA / Hibernate中很容易建模,这使得它非常复杂。如果您有兴趣看看这些问题

Mapping ManyToMany with composite Primary key and Annotation

Many to many hibernate mapping with extra columns?

答案 1 :(得分:0)

将用户包括在评级类

@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
// ...
}