Hibernate @ManyToMany关联:如何获取标签主键ID列表而非实体
如何在JPA中仅获取多对多关联的标签ID列表?
数据库结构
对应的多对多关联表结构如下:
CREATE TABLE `pages` ( `identifier` INT(11) NOT NULL auto_increment, `title` VARCHAR(150) NOT NULL, PRIMARY KEY (`identifier`) ); CREATE TABLE `tags` ( `identifier` INT(11) NOT NULL auto_increment, `name` VARCHAR(50) NOT NULL, PRIMARY KEY (`identifier`) ); CREATE TABLE `pages_tags` ( `page` INT(11) NOT NULL, `tag` INT(11) NOT NULL, KEY `pagetag_page` (`page`), KEY `pagetag_tag` (`tag`), CONSTRAINT `pages_tags_ibfk_1` FOREIGN KEY (`page`) REFERENCES `pages` (`identifier`), CONSTRAINT `pages_tags_ibfk_2` FOREIGN KEY (`tag`) REFERENCES `tags` (`identifier`) );
当前实体类关联定义
Page实体中原本的多对多关联定义如下,会加载完整的Tag实体列表:
@ManyToMany @JoinTable( name = "pages_tags", joinColumns = { @JoinColumn(name = "page", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "tag", nullable = false) } ) private List<Tag> tags;
需求
已知可以通过@NamedQuery单独查询标签ID:
@NamedQuery(name = "Page.findTags", query = "SELECT p.tag FROM PageTag p WHERE p.page = :identifier")
但希望直接在Page实体类中添加一个整数列表字段,让Hibernate自动映射pages_tags.tag字段的值,无需加载完整Tag实体。当前使用spring-boot-starter-data-jpa 3.0.0-RC1。
解决方案
可以使用@ElementCollection结合@CollectionTable来实现这个需求,直接映射关联表中的ID字段:
在Page实体中添加如下字段:
@ElementCollection @CollectionTable( name = "pages_tags", // 指定关联的中间表 joinColumns = @JoinColumn(name = "page") // 关联当前实体的外键列 ) @Column(name = "tag") // 要获取的标签ID列 private List<Integer> tagIds;
说明
- 这个配置会让Hibernate直接查询
pages_tags表中当前page对应的所有tag字段值,返回整数列表,无需加载Tag实体。 - 可以根据需要调整字段的获取策略(比如
fetch = FetchType.LAZY),避免不必要的查询。 - 如果不需要保留原有的
tags字段,可以将其移除;若需要同时存在,两者可以独立使用,互不干扰。
内容的提问来源于stack exchange,提问作者Emax
相关产品推荐
相关产品推荐

