In the functions getStartingPositions() & getSubstitutions() is only executed on playerId. That means if a player has different shirt numbers across one season, the join is not a 1-to-1 relationship which is required. matchId and squadId must be added as join clauses.