How to load only ids from Many to Many mapping tables?

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

In a Many to Many relation between two table with a Mapping table in between, how can I only load ids for the second entity.

Following is the example to explain what I want to achieve here. Below is a sample schema

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) ) 

Note: there are additional columns in user and page tables which i have not included here for brevity.

User entity:

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

What I want to do is add another attribute Set<Integer> pageIds in User class and have all page ids mapped for a user in this collection.

How can this be done using Hibernate?

回答1:

In User class:

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

You can get the id's by iterating over the returned set. By default collections are lazily (i.e. only ids) loaded.

EDIT: If you don't want to map Page for some reason, you can use @ElementCollection like this:

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


回答2:

I encountered a problem with the accepted answer, when I wanted to map both pages and pageIds. Hibernate will use both of these fields to make changes to the mapping table when a User is saved, possibly causing a lot of weird behaviour.

I instead solved this by making pageIds @Transient and populating the collection using @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()); } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!