0

NullPointerException after implementing an tournaments entity

I am trying to create seed data for use on client side testing w/ angular

This the relationship between the entities,

Games Entity

  • Games can only have 1 away team but team can have many away games
  • Games can only have 1 home team but team can have many home games
  • Games can only have 1 tournamnet but tournament can have many games

Games properties below, Games is not owning any of these relationships

    private Date date;
    
    private String location;
    
    @ManyToOne
    @JoinColumn(name="home_team_id")
    private Team home;
    
    @ManyToOne
    @JoinColumn(name="away_team_id")
    private Team away;
    
    @ManyToOne(optional = true)
    @JoinColumn(name="tournament_id")
    private Tournaments tournament;

Now Player,

  • player can only have 1 stats and stats can only be assigned 1 player, player owns this relationship
  • Player can only be part of 1 team and a team can have many, Team owns this relationship

Player entity below,

    @OneToOne(mappedBy = "player", cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private PlayerStats stats;
    
    @ManyToOne
    @JoinColumn(name= "team_id")
    private Team team;
    
    private String name;
    
    @Enumerated(EnumType.STRING)
    private TeamRole position;

Now Team,

  • Team is asigned 1 team stats and teamstats can only be assigned with 1 team, teams owns this relationship
  • Team can have many players and players can only have 1 team, teams owns this relationship
  • Team can have many homeGames but Games can only have one home team, same for teams awayGames, teams owns this relationship
  • Team can have many tournaments and tournaments can have many teams, tournaments own this relationship Team entity below, Note console references this entity, commented the line in which the console is referencing
    private String name;
    
    @OneToOne(mappedBy = "team", cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private TeamStats stats;
    
    @OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Player> players;
    
    @OneToMany( mappedBy = "home", cascade = CascadeType.ALL )
    private List<Games> homeGames;

    @OneToMany( mappedBy= "away", cascade = CascadeType.ALL )
    private List<Games> awayGames;
    
    //MANY TEAMS TO MANY 
    @ManyToMany(mappedBy="numOfParticpants")
    private List<Tournaments> upcommingTournaments;
    
    public void addPlayer(Player player) {
        players.add(player);//console reference this line
        player.setTeam(this);
    }
    
    public void removePlayer(Player player) {
        players.remove(player);
        player.setTeam(null);
    }
    
    public void addHomeGame(Games game) {
        homeGames.add(game);
        game.setHome(this);
    }
    public void removeHomeGame(Games game) {
        homeGames.remove(game);
        game.setHome(null);
    }
    public void addAwayGame(Games game) {
        awayGames.add(game);
        game.setAway(this);
    }
    public void removeAwayGame(Games game) {
        awayGames.remove(game);
        game.setAway(null);
    }

Now all my implementations worked perfectly fine before implementing the tournaments entity and its relationships with the other entities so my, loadPlayerTeamData() & loadGamesData() worked perfectly fine until I implemented loadTournamentsData() and the tournaments entity and its relationships

  • Tournament can have many participants(Team) and a Team can participate in many tournaments
  • Tournament can have many games but a game can only be assigned to one tournament, IF a game is for a tournament otherwise the game will null value if game is just exhibition

Tournament owns all these relationships

Tournament entity

    private String name;
    
    private Date scheduledDate;
    
    //MANY TOURNAMENTS TO MANY TEAMS
    @ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
    @JoinTable(
            name= "tournament_participants",
            joinColumns= @JoinColumn(name = "team_id"),
            inverseJoinColumns= @JoinColumn(name="tournament_id")
        )
    private List <Team> numOfParticpants;
    
    @OneToMany(mappedBy="tournament", cascade = CascadeType.ALL)
    private List <Games> totalGames;
    
    private String location;
    
    private TournamentSize tournamentSize;

    public void addParticipant(Team team) {
        this.numOfParticpants.add(team);
        team.getUpcommingTournaments().add(this);
    }
    
    public void removeParticipant(Team team) {  
        this.numOfParticpants.remove(team);
        team.getUpcommingTournaments().remove(this);
    }
    public void addGame(Games game) {
        this.totalGames.add(game);
        game.setTournament(this);
    }
    public void removeGame(Games game) {
        this.totalGames.remove(game);
        game.setTournament(null);
    }

Again, everything was working fine before implementing tournaments and its relationships, no null pointer exception, no errors at all, my databases were being populated

My question is, WHAT WENT WRONG LOL, i get a nullPointException within my loadPlayerTeamDataSeed() when before implementing tournaments this wasnt a issue.

Console,

Caused by: java.lang.NullPointerException: Cannot invoke "java.util.List.add(Object)" because "this.players" is null
    at com.unknown.server.model.Team.addPlayer(Team.java:105) ~[classes/:na]
    at com.unknown.server.dataseed.DataSeed.loadPlayerTeamData(DataSeed.java:88) ~[classes/:na]
    at com.unknown.server.dataseed.DataSeed.run(DataSeed.java:55) ~[classes/:na]

Seeding implementation below,

    private void loadPlayerTeamData() {
        List<Team> teamList = teamService.getAllTeams().get();
        
        Team team = new Team();
        
        while(teamList.size() < 50) {
            //set player name and position
            Player player = new Player();
            player.setName(faker.name().fullName());
            player.setPosition(TeamRole.randomRole());
            
            //set playerStats
            PlayerStats playerStats = new PlayerStats(
                    player, 
                    faker.number().numberBetween(1, 20),
                    faker.number().numberBetween(1, 20),
                    faker.number().numberBetween(1, 20),
                    faker.number().numberBetween(2, 40),
                    faker.number().numberBetween(1, 20),
                    faker.number().numberBetween(1, 20));
            
            player.setStats(playerStats);
            
            //add player to team
            team.addPlayer(player); //This what the console is refering to
            if(team.getPlayers().size() >= 10) {
                //Set team and teamStats data
                int assists = 0, blocks = 0, 
                    points = 0, rebounds = 0, 
                    steals = 0, turnovers = 0;
                for(Player p: team.getPlayers()) {
                    assists =assists+p.getStats().getAssist();
                    blocks= blocks+p.getStats().getBlocks();
                    points= points+p.getStats().getPoints();
                    rebounds= rebounds+p.getStats().getRebounds();
                    steals= steals+p.getStats().getRebounds();
                    turnovers= turnovers+p.getStats().getTurnovers();
                }
                TeamStats teamStats = new TeamStats(
                        rebounds/team.getPlayers().size(), 
                        assists/team.getPlayers().size(), 
                        blocks/team.getPlayers().size(), 
                        points/team.getPlayers().size(), 
                        steals/team.getPlayers().size(), 
                        turnovers/team.getPlayers().size());
                team.setName(faker.pokemon().name());
                team.setStats(teamStats);
                
                teamService.addTeam(team);
                
                team = new Team();
                teamList = teamService.getAllTeams().get();
            }
        }
        
    }
    
    //3 away games and 3 home games per team 
    private void loadGamesData() {
        List<Games> games = new ArrayList<Games>();
            
        List<Team> teams = teamService.getAllTeams().get();
            
        while(teams.size() > 1) {
            Team t = teams.get(0);
            teams.remove(0);
            while(t.getHomeGames().size() < 2) {
                int a = teams.size() == 2 ? faker.number().numberBetween(teams.size()/2, teams.size()-1) : faker.number().numberBetween(0, teams.size()-1);
                
                Date d = faker.date().future(1, TimeUnit.DAYS);
                String location = faker.address().fullAddress();
                
                Team opp = teams.get(a);
                
                Games game = new Games(d, location, t, opp, null);
                t.addHomeGame(game);
                opp.addAwayGame(game);
                games.add(game);
            }
            while(t.getAwayGames().size() < 2) {
                int a = teams.size() == 2 ? faker.number().numberBetween(0, teams.size()/2) : faker.number().numberBetween(0, teams.size()-1);
                
                Date d = faker.date().future(1, TimeUnit.DAYS);
                String location = faker.address().fullAddress();
                
                Team opp = teams.get(a);
                
                Games game = new Games(d, location, opp, t, null);
                t.addAwayGame(game);
                opp.addHomeGame(game);
                games.add(game);
            }
        }
            
        for(Games g: games) {
            gamesService.addGame(g);
        }
    }
    
    private void loadTournamentsData() {
        List<Tournaments> tournies = new ArrayList<>();
        
        List<Team> teams = teamService.getAllTeams().get();
        
        List<Team> scheduled = new ArrayList<>();
        
        while(tournies.size() < 10){
            Tournaments tournie = new Tournaments();
            String location = faker.address().fullAddress();
            tournie.setName(faker.pokemon().name());
            tournie.setLocation(location);
            tournie.setScheduledDate(faker.date().future(50, TimeUnit.DAYS));
            
            //populate list of participants and add to tournament
            for(int i = 0; i < TournamentSize.fixedSize(TournamentSize.EIGHT); i++) {
                Team team = teams.get(faker.number().numberBetween(0, teams.size()-1));
                scheduled.add(team);
                teams.remove(team);
                tournie.addParticipant(team);
            }
            
            //create games
            int opp1 = 0, opp2 = scheduled.size()-1;
            while(opp1 < opp2) {
                Team home = scheduled.get(opp1);
                Team away = scheduled.get(opp2);
                
                Games game = new Games(
                        faker.date().future(52, TimeUnit.DAYS),
                        location,
                        home,
                        away,
                        null
                        );
                tournie.addGame(game);
                opp1++;
                opp2--;
            }
            tournies.add(tournie);
            scheduled.clear();
        }
        for(Tournaments t: tournies) {
            tournamentsService.addTournament(t);
        }
        
    }

It's important to remember before implementing the tournaments entity and its classes this was not a issue, should I use NoSQL instead of SQL, I know that would probably be best but SQL works for alot of my data except for tournaments it seems.

THank you to anyone who tries to help

  • You never assign a value to your lists: `private List players;` is initialized with `null` and you never set it to a different value. – knittl Jul 13 '22 at 19:53
  • Yes this makes sense actually, from both answers. So I need to set the list when I set the relationship as such `@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)` `private List players = new ArrayList<>();` – James Cervantes Jul 14 '22 at 19:20
  • ***UPDATE***, I understand lol, power of contructors lol, I set my contructors to init entity lists – James Cervantes Jul 14 '22 at 19:43

1 Answers1

0

In loadPlayerTeamData() you create a new Team Team team = new Team(); and than you try to add a player on a not initialized players list

pL4Gu33
  • 2,045
  • 16
  • 38