【问题标题】:How to load only ids from Many to Many mapping tables?如何仅从多对多映射表加载 id?
【发布时间】:2013-06-04 16:46:33
【问题描述】:

在两个表之间有一个映射表的多对多关系中,我怎样才能只加载第二个实体的 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 做到这一点?

【问题讨论】:

    标签: hibernate hibernate-mapping hibernate-annotations


    【解决方案1】:

    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;
    

    【讨论】:

    • 有什么方法可以在不使用 Page 类的情况下只加载集合中的 ID?即向具有所有 id 的 User 类添加另一个属性 Set
    【解决方案2】:

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

    我改为solved this,通过创建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());
    }
    

    【讨论】:

    • 我认为 Hibernate 需要急切地将所有 Page 对象加载到内存中来实现这一点,如果有很多 Page 对象或者 Page 对象有很多关联并且属性。
    猜你喜欢
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 2012-07-08
    • 1970-01-01
    • 2016-06-17
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多