如何通过Hibernate从数据库视图将同一ID的名称列映射为实体列表
实现同一ID下name值的List聚合方案
你当前的实体映射存在问题:@Column无法直接映射为List<String>,且嵌入式ID包含sub_id会导致每条视图记录被映射为独立的Entity实例,无法完成聚合。以下是两种可行的解决思路:
方案一:修改实体映射,结合数据库聚合函数
1. 重新定义实体
去掉嵌入式ID中的sub_id,通过数据库聚合函数将同一id下的去重name聚合为集合:
@Entity(name = "entity") @Immutable @NamedNativeQuery( name = "Entity.findByMainId", // PostgreSQL语法,其他数据库需替换对应聚合函数 query = "SELECT id, ARRAY_AGG(DISTINCT name) AS names FROM entity WHERE id = ?1 GROUP BY id", resultClass = Entity::class ) class Entity( @Id val id: Long, @Column(name = "names") @ElementCollection(targetClass = String::class) val data: List<String> )
- 不同数据库聚合函数差异:
- MySQL:使用
GROUP_CONCAT(DISTINCT name SEPARATOR ','),需将结果字符串拆分为List - Oracle:使用
LISTAGG(DISTINCT name, ',') WITHIN GROUP (ORDER BY sub_id),同样需拆分字符串
- MySQL:使用
2. 执行查询获取数据
val targetId = 1L // 替换为你要查询的id val entity = entityManager.createNamedQuery("Entity.findByMainId", Entity::class.java) .setParameter(1, targetId) .singleResult
方案二:保持原实体,通过JPQL直接查询聚合结果
无需修改实体结构,直接查询指定id下的所有去重name:
val targetId = 1L // 替换为你要查询的id val namesList = entityManager.createQuery( "SELECT DISTINCT e.name FROM entity e WHERE e.id.id = :mainId", String::class.java ) .setParameter("mainId", targetId) .resultList
内容的提问来源于stack exchange,提问作者Osama A.Rehman
相关产品推荐
相关产品推荐

