I'm new to Spring-boot and MongoDB. In MongoDB a manual reference between two collections works fine. The mapping in Spring-boot seems not to work. I really don't know what else to check.Below all the relevant details, sorry for the long question.
The reason not to use DBref is because I might need the projections.
The "players" collection has this schema(any other not allowed)
{"_id":{"$oid":"5f56021d61738cc35de79438"},
"name":"Romeo",
"entryDate":{"$date":"2020-08-23T22:00:00.000Z"}}`
The "games" collection has the following schema
{
"_id":{"$oid":"5f5614a361738cc35de7943b"},
"dices":{
"value1":1,
"value2":6
},
"gameScore":1,
"player_id":{"$oid":"5f56021d61738cc35de79438"}
}
The aggregation in MongoDB Compass
[{
$match: {
_id: ObjectId('5f56021d61738cc35de79438')
}
}, {
$lookup: {
from: 'games',
localField: '_id',
foreignField: 'player_id',
as: 'games'
}
}]
yields
In Spring-boot the POJOs are:
@Document(collection = "players")
public class Player {
@Id
private String id;
private String name;
private LocalDate entryDate= LocalDate.now();
private List<Game> game;
public Player(){};
public Player(String name) {
this.name = name;
}
//getters and setters for all properties, including game
}
@Document(collection = "games")
public class Game {
@Id
private String id;
private Dices dices;
private Integer gameScore;
@Field(value = "player_id")
private String playerId;
public Game(){};
public Game(Dices dices) {
this.dices = dices;
}
//getters and setters for all properties
}
public class Dices {
private int value1;
private int value2;
public Dices(){}
public Dices(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
//getters and setters for both properties
In Postman
GET findAll players shows:
[{"id":"5f56021d61738cc35de79438","name":"Romeo","entryDate":[2020,8,24],"game":null},{"id":"5f5602e361738cc35de79439","name":"Julieta","entryDate":[2020,8,24],"game":null}, ....]
game is shown because I added also getters and setters for this property, just trying to find the way to properly mapping the games as manual references to players
GET findAll games:
[{"id":"5f5614a361738cc35de7943b","dices":{"value1":1,"value2":6},"gameScore":1,"playerId":"5f56021d61738cc35de79438"},
{"id":"5f5619f561738cc35de7943c","dices":{"value1":2,"value2":5},"gameScore":1,"playerId":"5f5602e361738cc35de79439"},
{"id":"5f561a5461738cc35de7943d","dices":{"value1":3,"value2":3},"gameScore":0,"playerId":"5f56021d61738cc35de79438"}, ...]
GET lh:8080/players/5f56021d61738cc35de79438/games yields an empty array, this is why I assume that the mapping between the collections in Spring-boot fails.
The GamesRepository
@Repository
public interface GameRepository extends MongoRepository<Game, String> {
List<Game> findAll();
List<Game> findGamesByPlayerId(String playerId);
}
The method in the service
@Override
public List<Game> findAllGamesByPlayerId(String playerId) {
Optional<Player> playerDB= playerRepository.findById(playerId);
if(playerDB.isPresent()) {
return gameRepository.findGamesByPlayerId(playerId);
}
else throw new ResourceNotFoundException("Player with id: "+playerId+" does not exist");
}
and the GameController
@GetMapping("/{ID}/games")
public ResponseEntity<List<Game>> getAllGamesByPlayerId (@PathVariable("ID") String playerId){
return ResponseEntity.ok()
.body(gameService.findAllGamesByPlayerId(playerId));
}
Tips are welcome!