JDBI3嵌套SQLObject:@Nested注解查询关联复合对象时嵌套字段为null
JDBI3 嵌套复合对象映射的问题排查与修正
核心错误根因
你当前的实现存在两个关键的认知偏差,直接导致author字段映射为null:
- 分开注册两个独立BeanMapper不会自动完成对象组装:在DAO方法上分别给e前缀的Event、a前缀的Author注册独立Mapper时,两个Mapper是独立执行的——各自把行数据拆成Event实例和Author实例,但没有任何内置逻辑会把生成的Author实例赋值到Event的author字段上。Author实例映射完成后直接被丢弃,自然填充不到Event对象里。
- @Nested注解不是“打了就生效”的独立开关:它需要和JDBI的嵌套BeanMapper解析流程绑定才能工作,单独给字段加@Nested、再额外独立注册关联对象Mapper的组合,完全触发不了嵌套映射逻辑。
修正实现步骤
1. 调整DAO层的Mapper注册逻辑
删掉单独给Author注册的@RegisterBeanMapper,只保留主对象Event的Mapper注册:
@SqlQuery("SELECT e.id as e_id, e.name as e_name, e.start_time as e_start_time, e.lastupdated as e_lastupdated, a.id as a_id, a.name as a_name, a.mail_address as a_mail_address FROM event e INNER JOIN author a ON(e.author_id = a.id) WHERE e.id = :event_id") // 仅保留主对象Event的Mapper注册,移除原来单独注册Author的@RegisterBeanMapper行 @RegisterBeanMapper(value = Event.class, prefix = "e") List<Event> getFeedbackByEventId(@Bind("event_id") int eventId);
注意:原方法里的
@Bind("author_id")参数在SQL中没有被实际引用,属于冗余参数,可以直接删除。
2. 排查@Nested注解的生效障碍
你在Event类的author字段上加@Nested("a") 的位置和写法是对的,只需要确认两个高频踩坑点:
- 必须引入JDBI核心包下的
org.jdbi.v3.core.mapper.Nested注解,不要导入其他第三方库的同名注解,否则注解会完全失效。 - JDBI 3.10.0之前的版本,嵌套映射能力属于
jdbi3-beans扩展模块,需要确认项目引入了对应依赖,否则注解不会被解析。
满足以上条件后,JDBI的BeanMapper在解析Event对象时,会自动识别author字段上的@Nested("a") 标记,以"a_"作为列前缀,把所有a_开头的列映射成Author实例,直接赋值到event的author字段,完全不需要手写自定义RowMapper。
自动匹配规则说明
嵌套映射时,JDBI会自动去掉列名指定的前缀,和Author类的字段做驼峰匹配:
a_id列 → 映射到Author的id字段a_name列 → 映射到Author的name字段a_mail_address列 → 自动转驼峰后映射到Author的mailAddress字段
扩展:1对多嵌套关系的适配
如果实际业务是Event对应多个Author(字段类型为List<Author>),@Nested 仅支持单值对象的嵌套映射,无法直接处理多值聚合场景,需要使用JDBI提供的@JoinBeanMapper 注解配合List字段完成结果聚合,避免JOIN产生的多行数据拆分后重复生成Event实例。
内容的提问来源于stack exchange,提问作者BeJay
相关产品推荐
相关产品推荐

