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

SpringBoot+MongoDB无法向List中添加对象问题求助

问题分析与解决方案

核心问题

  1. 未显式持久化Player实体变更:MongoDB的Spring Data框架不会像JPA那样自动跟踪实体状态修改,仅修改Player的games列表后,必须调用playerRepository.save()才能将变更同步到数据库。
  2. DBRef关联的Game未提前持久化:@DBRef存储的是关联文档的ID,必须先将Game保存到数据库生成gameId,再将其添加到Player的games列表,否则关联关系无法生效。

具体修改方案

1. 调整GameServiceImpl的playGame方法

先保存Game生成ID,再更新Player的关联关系,最后持久化Player:

@Override
public Game playGame(String playerId) {
    if(playerService.getAllPlayers().isEmpty()){
        throw new HttpException(HttpStatus.INSUFFICIENT_STORAGE,"There is no registered player");
    }
    Player player = playerService.findPlayerById(playerId);
    if(player==null){
        throw new HttpException(HttpStatus.NOT_FOUND,"Player with this id is not found");
    }

    Game gamePlayed = playGameService.play();
    gamePlayed.setPlayer(player);
    // 先保存Game,生成唯一ID
    Game savedGame = gameRepository.save(gamePlayed);
    
    player.calculateRate();
    // 将已持久化的Game添加到Player列表,并保存Player
    playerService.saveGame(savedGame, playerId);
    
    return savedGame;
}

2. 修改PlayerServiceImpl的saveGame方法

添加Player的显式保存逻辑:

@Override
public void saveGame(Game game, String playerId){
    Optional<Player> playerOpt = playerRepository.findById(playerId);
    if(playerOpt.isPresent()){
        Player player = playerOpt.get();
        player.getGames().add(game);
        // 持久化Player的关联变更
        playerRepository.save(player);
    }
}

补充说明

  • 原MySQL环境中JPA的EntityManager会自动托管实体修改,无需手动调用save;但MongoDB的Spring Data无此特性,必须手动触发持久化操作。
  • @DBRef会在Player文档中存储Game的ID引用,结合Game配置的lazy=true,查询Player时可按需懒加载关联的Game列表。

内容的提问来源于stack exchange,提问作者Anna kuzmina

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:07:53