16

在两个表之间的多对多关系中,中间有一个映射表,我怎样才能只加载第二个实体的 ID。

以下是解释我想要在这里实现的目标的示例。下面是一个示例架构

create table user(
 id int PrimaryKey,
 name text
)
create table pages (
 id int PrimaryKey,
 page_name text
)
create table user_page (
 id_user int,
 id_page int,
 PrimaryKey (id_user, id_page)
)

注意:用户表和页表中还有其他列,为简洁起见,我没有在此处包括在内。

用户实体:

@Entity
@Table(name = "user")
public class User {
 @id
 @column(name="id")
 private Integer id;
 @column(name="name")
 private String name;
 ... 
 ...
}

@Entity
@Table(name = "page")
public class Page {
 @id
 @column(name="id")
 private Integer id;
 @column(name="page_name")
 private String name;
 ... 
 ...
}

我想要做的是Set<Integer> pageIdsUser类中添加另一个属性,并为该集合中的用户映射所有页面 id。

如何使用 Hibernate 来做到这一点?

4

2 回答 2

33

User课堂上:

@ManyToMany
@JoinTable(
    name="user_page",
    joinColumns = @JoinColumn(name="id_user"),
    inverseJoinColumns = @JoinColumn(name="id_page")
)
public Set<Page> pages;

您可以通过遍历返回的集合来获取 id。默认情况下,集合是延迟加载的(即只有 id)。

编辑:如果您出于某种原因不想映射Page,可以@ElementCollection这样使用:

@ElementCollection
@CollectionTable(name="user_page", joinColumns=@JoinColumn(name="id_user"))
@Column(name="id_page")
public Set<Long> pageIds;
于 2013-06-09T00:59:47.903 回答
0

当我想同时映射pages和时,我遇到了接受的答案的问题pageIds。当保存 a 时,Hibernate 将使用这两个字段来更改映射表User,这可能会导致很多奇怪的行为。

相反,我通过使用以下方法制作和填充集合来解决这个问题pageIds @Transient@PostLoad

@ManyToMany
@JoinTable(
    name="user_page",
    joinColumns = @JoinColumn(name="id_user"),
    inverseJoinColumns = @JoinColumn(name="id_page")
)
public Set<Page> pages;

@Transient
public Set<Long> pageIds;

@PostLoad
private void postLoad() {
    pageIds = pages.stream().map(Page::getId).collect(Collectors.toSet());
}
于 2017-08-07T17:03:07.557 回答