Azure Spring Data Cosmos Java实体属性名映射方法咨询
现有一个用于DynamoDB的Java实体类,需在同一应用中持久化到Cosmos DB。当前应用使用AWS DynamoDB库,可通过@DynamoDBAttribute注解实现实体属性与集合中字段名的映射:
@Getter @Setter class DynamoEntity { @DynamoDBAttribute(attributeName = "attr_inside_collection") private String attr; }
目前使用azure-spring-data-cosmos v5.5操作Cosmos DB,但未找到类似的属性名覆盖注解(仅支持@PartitionKey、@CompositeIndex等映射)。需求是让Cosmos DB中存储的字段名与DynamoDB一致,同时保持实体类属性的简洁命名(当前需将实体属性名与集合字段名一致,较为冗余)。尝试过@JsonProperty注解及实现Serializable接口均无效,仅@Id注解可实现名称映射。
请问是否存在方法,使Cosmos实体类属性名与容器中存储的字段名不同?
针对azure-spring-data-cosmos v5.5版本,有两种可行方式实现实体属性与Cosmos DB存储字段名的映射:
1. 配置Jackson序列化生效@JsonProperty
你之前尝试@JsonProperty无效,是因为默认情况下Cosmos的转换器未启用Jackson的注解解析。通过自定义配置让@JsonProperty生效:
步骤1:添加Cosmos配置类
import com.azure.spring.data.cosmos.config.CosmosConfig; import com.azure.spring.data.cosmos.config.CosmosConfigBuilder; import com.azure.spring.data.cosmos.core.convert.MappingCosmosConverter; import com.azure.spring.data.cosmos.core.mapping.CosmosMappingContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class CosmosDbConfig { @Bean public CosmosConfig cosmosConfig() { return new CosmosConfigBuilder().build(); } @Bean public MappingCosmosConverter mappingCosmosConverter(CosmosMappingContext cosmosMappingContext, Jackson2ObjectMapperBuilder objectMapperBuilder) { MappingCosmosConverter converter = new MappingCosmosConverter(cosmosMappingContext); converter.setObjectMapper(objectMapperBuilder.build()); return converter; } }
步骤2:在实体类中使用@JsonProperty
@Getter @Setter @Container(containerName = "your-target-container") class CosmosEntity { @Id private String id; @JsonProperty("attr_inside_collection") private String attr; }
2. 全局配置命名策略
如果你的DynamoDB字段统一使用下划线格式,可配置Jackson的全局命名策略,自动将驼峰属性名转为下划线存储,无需逐个字段加注解:
修改上述配置类中的mappingCosmosConverter方法:
import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.ObjectMapper; // ... 其他导入代码 @Bean public MappingCosmosConverter mappingCosmosConverter(CosmosMappingContext cosmosMappingContext, Jackson2ObjectMapperBuilder objectMapperBuilder) { MappingCosmosConverter converter = new MappingCosmosConverter(cosmosMappingContext); ObjectMapper objectMapper = objectMapperBuilder .propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) .build(); converter.setObjectMapper(objectMapper); return converter; }
此时实体类中private String attr;会自动映射为Cosmos DB中的attr,如果是private String userName;则会映射为user_name,完全匹配DynamoDB的下划线命名风格。
内容的提问来源于stack exchange,提问作者phramos07

