You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:46:02