如何仅从多对多映射表加载id



在两个表之间有一个映射表的多对多关系中,如何只加载第二个实体的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;
 ... 
 ...
}

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

如何使用Hibernate实现?

In User class:

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

可以通过迭代返回的集合来获得id。默认情况下,集合是惰性加载的(即只加载id)。

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

@ElementCollection
@CollectionTable(name="user_page", joinColumns=@JoinColumn(name="id_user"))
@Column(name="id_page")
public Set<Long> pageIds;

当我想映射pagespageIds时,我遇到了一个接受答案的问题。当保存User时,Hibernate将使用这两个字段对映射表进行更改,这可能会导致许多奇怪的行为。

我通过使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());
}

相关内容

  • 没有找到相关文章

最新更新