Spring Data JDBC复合ID保存时SQL未包含租户ID问题求助
问题原因及解决方案
原因分析
Spring Data JDBC 在处理**复合ID(尤其是实现JMolecules Identifier接口的record类型)**时,默认不会自动拆解复合ID的内部属性映射到数据库列,除非显式配置属性与列的关联关系。
你的ServiceId作为record类型实现了Identifier接口,但未明确标注每个属性对应的数据库列;同时Spring Data JDBC与JMolecules结合使用时,框架没有自动识别到复合ID的内部属性需要作为独立列参与SQL生成,导致tenantId被忽略。
解决方案
方案1:给复合ID属性添加列映射注解
在ServiceId的record参数上添加@Column注解,明确指定每个属性对应的数据库列名:
import org.springframework.data.relational.core.mapping.Column; record ServiceId( @Column("tenant_id") UUID tenantId, @Column("id") UUID id ) implements Identifier { }
方案2:配置自定义命名策略(可选)
如果不想逐个添加注解,可以配置Spring Data JDBC的命名策略,让框架自动将驼峰命名的属性转换为下划线命名的列(如tenantId转为tenant_id)。创建配置类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jdbc.core.mapping.NamingStrategy; import org.springframework.data.jdbc.core.convert.SqlIdentifier; @Configuration public class JdbcConfig { @Bean public NamingStrategy namingStrategy() { return new NamingStrategy() { @Override public SqlIdentifier getColumnName(SqlIdentifier name) { String columnName = name.getReference() .replaceAll("([a-z])([A-Z])", "$1_$2") .toLowerCase(); return SqlIdentifier.unquoted(columnName); } }; } }
确保ServiceId的属性名与数据库列名的转换规则匹配,框架就能自动识别tenantId对应tenant_id列。
方案3:排查JMolecules注解干扰
若上述方案无效,可暂时移除@AggregateRoot注解测试,确认是否是JMolecules注解干扰了Spring Data JDBC的ID解析逻辑。若移除后SQL生成正常,需调整JMolecules与Spring Data JDBC的集成配置,确保复合ID的属性能被正确解析。
内容的提问来源于stack exchange,提问作者Ziemowit Stolarczyk
相关产品推荐
相关产品推荐

