You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blaze Persistence子查询中如何使用可选参数实现关联字段映射

错误原因

你遇到的报错是因为EMBEDDING_VIEW()函数仅支持引用和原实体(Topic)关联的视图属性,通过@MappingParameter注入的可选参数不属于实体属性,无法通过该函数读取。

解决方案

有两种常用实现方式,都不需要修改数据库表结构:

方案1:修改子查询参数引用方式

直接在子查询中通过:参数名的格式引用@MappingParameter定义的视图参数,修正后的代码如下:

@EntityView(Topic.class)
public interface TopicView
{
    @IdMapping
    Long getId();

    String getSummary();

    @MappingParameter("currentUserId")
    Long getCurrentUserId();

    @MappingSubquery(LastSeenDateSubqueryProvider.class)
    Date getLastSeenDate();

    class LastSeenDateSubqueryProvider implements SubqueryProvider
    {
        @Override
        public <T> T createSubquery(SubqueryInitiator<T> subqueryBuilder)
        {
            return subqueryBuilder.from(TopicLastSeen.class, "lastSeen")
                    .select("dateSeen")
                    // 直接引用参数名,不需要用EMBEDDING_VIEW包裹
                    .where("lastSeen.user.id").eq(":currentUserId")
                    .where("lastSeen.topic.id").eqExpression("EMBEDDING_VIEW(id)")
                    .end();
        }
    }
}

查询时正常传入参数即可:

EntityViewSetting<TopicView, Long> setting = EntityViewSetting.create(TopicView.class);
// 传入当前登录用户ID
setting.addParameter("currentUserId", loginUserId);
List<TopicView> result = entityViewManager.applySetting(setting, topicCriteriaBuilder).getResultList();

方案2:简化为直接JPQL映射(更简洁)

如果不需要复杂的子查询逻辑,可以直接用@Mapping注解写单值子查询,不需要单独实现SubqueryProvider:

@EntityView(Topic.class)
public interface TopicView
{
    @IdMapping
    Long getId();

    String getSummary();

    @MappingParameter("currentUserId")
    Long getCurrentUserId();

    @Mapping("SELECT l.dateSeen FROM TopicLastSeen l WHERE l.topic.id = id AND l.user.id = :currentUserId")
    Date getLastSeenDate();
}

如果用户没有对应话题的阅读记录,该字段会自动返回null,符合业务需求。

内容的提问来源于stack exchange,提问作者cg.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:06:09