Spring Boot集成MongoDB:MongoTemplate无法获取嵌套对象求助
问题:MongoTemplate.findOne无法获取User对象中的profile和roles属性
我正在学习使用Spring Boot实现MongoDB相关功能,目前遇到问题:调用MongoTemplate.findOne时,始终无法获取User对象中的profile和roles属性,它们的值始终为null。
相关代码
User实体类
@Document(collection = "users") @Data @ToString public class User { @MongoId(targetType = FieldType.OBJECT_ID) private String id; @Size(max = 20) @NotBlank private String username; @NotBlank @Size(max = 50) @Email private String email; @NotBlank private String passwordHash; private Set<Role> roles = new HashSet<>(); private Profile profile; private Date createdAt; private Date updatedAt; public User() { this.createdAt = new Date(); this.updatedAt = new Date(); } public User(String username, String email, String passwordHash, String firstName, String lastName, String bio, String profilePicture) { this.profile = new Profile(firstName, lastName, bio, profilePicture); this.username = username; this.email = email; this.passwordHash = passwordHash; this.createdAt = new Date(); this.updatedAt = new Date(); } public User(String username, String email, String passwordHash) { this.username = username; this.email = email; this.passwordHash = passwordHash; this.createdAt = new Date(); this.updatedAt = new Date(); } public User(String username, String email, String passwordHash, Profile profile) { this(username, email, passwordHash); this.profile = profile; } @Data @ToString @AllArgsConstructor @NoArgsConstructor public static class Profile { @Size(max = 50) @NotBlank private String firstName; @Size(max = 50) @NotBlank private String lastName; @Size(max = 300) private String bio; private String profilePicture; } }
Role实体类
@Document(collection = "roles") @Data @NoArgsConstructor @ToString public class Role { @MongoId(targetType = FieldType.OBJECT_ID) private String id; private String description; private String roleName; private List<String> permissions; @CreatedDate private Date createAt; @LastModifiedDate private Date updateAt; }
UserDao中的findByUsername方法
public Optional<User> findByUsername(String username) { Query query = new Query(); query.addCriteria(Criteria.where("username").is(username)); query.fields() .include("username") .include("email") .include("createdAt") .include("roles") .include("passwordHash") .include("profile"); Optional<User> user = Optional.ofNullable(mongoTemplate.findOne(query, User.class)); return user; }
解决方案
1. 配置Roles的关联查询
User类中的roles字段指向独立的Role集合文档,需要添加@DBRef注解,让MongoTemplate自动执行关联查询:
@DBRef private Set<Role> roles = new HashSet<>();
注意:数据库中user文档的roles字段需存储Role文档的ObjectId数组(如["60d21b4667d0d8992e610c85"]),而非Role的完整嵌套文档。
2. 确保Profile字段映射匹配
检查MongoDB中user文档的profile嵌套结构与Profile类字段的命名一致性:
- 若数据库使用下划线命名(如
first_name),需给Profile字段添加@Field注解指定映射:
@Data @ToString @AllArgsConstructor @NoArgsConstructor public static class Profile { @Field("first_name") @Size(max = 50) @NotBlank private String firstName; @Field("last_name") @Size(max = 50) @NotBlank private String lastName; @Size(max = 300) private String bio; private String profilePicture; }
- 若数据库已使用驼峰命名(如
firstName),则无需额外配置,Spring Data Mongo会自动映射。
3. 简化查询逻辑(推荐)
若需要获取完整的User对象,无需手动指定include字段,移除query.fields()部分即可默认加载所有字段,避免字段遗漏或名称错误:
public Optional<User> findByUsername(String username) { Query query = new Query(Criteria.where("username").is(username)); return Optional.ofNullable(mongoTemplate.findOne(query, User.class)); }
4. 验证数据库数据
确认MongoDB中目标user文档:
- 存在非空的
profile嵌套文档 roles字段包含有效的Role文档ObjectId数组
内容的提问来源于stack exchange,提问作者Robin Singh
相关产品推荐
相关产品推荐

