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.
相关产品推荐
相关产品推荐

