0

everyone. I'm trying to build a gaming app, but have encountered a problem. I created a Spring Repository, Entity and Service, but whenever I call the latter I encounter an exception stating:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.example.demo.repo.PlayerRepository.findById(Object)" because "this.playerRepository" is null
    at com.example.demo.service.PlayerService.findPlayerById(PlayerService.java:16)
    at com.example.demo.DemoApplication.main(DemoApplication.java:16)

Here are my classes provided to show what I included in the program:

PlayerEntity:

package com.example.demo.model;

import javax.persistence.*;
import java.util.Objects;

@Entity
@Table(name = "player", schema = "public", catalog = "gamestats")
public class PlayerEntity {
    private long id;
    private int health;
    private int damage;
    private int absorb;
    private int regen;
    private int fire;

    @Id
    @Column(name = "id")
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Basic
    @Column(name = "health")
    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        this.health = health;
    }

    @Basic
    @Column(name = "damage")
    public int getDamage() {return this.damage; }

    public void setDamage(int damage) {
        this.damage = damage;
    }

    @Basic
    @Column(name = "absorb")
    public int getAbsorb() {
        return absorb;
    }

    public void setAbsorb(int absorb) {
        this.absorb = absorb;
    }

    @Basic
    @Column(name = "regen")
    public int getRegen() {
        return regen;
    }

    public void setRegen(int regen) {
        this.regen = regen;
    }

    @Basic
    @Column(name = "fire")
    public int getFire() {
        return fire;
    }

    public void setFire(int fire) {
        this.fire = fire;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PlayerEntity that = (PlayerEntity) o;
        return id == that.id && health == that.health && damage == that.damage && absorb == that.absorb && regen == that.regen && fire == that.fire;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, health, damage, absorb, regen, fire);
    }
}

Player Repository:

package com.example.demo.repo;

import com.example.demo.model.PlayerEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface  PlayerRepository extends JpaRepository<PlayerEntity, Long> {
}

Player Service:

package com.example.demo.service;

import com.example.demo.model.PlayerEntity;
import com.example.demo.repo.PlayerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PlayerService{
    @Autowired
    PlayerRepository playerRepository;

    private PlayerEntity playerEntity;

    public PlayerEntity findPlayerById(long id) {
        return playerRepository.findById(id).get();
    }

    public void safePlayer(PlayerEntity test){ playerRepository.save(test); }


    public int getPlayerStrength(long id) {
        return playerRepository.findById(id).get().getHealth();
    }
}

DemoApplication:

package com.example.demo;

import com.example.demo.service.PlayerService;
import org.json.JSONException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.IOException;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) throws IOException, InterruptedException, JSONException {
        SpringApplication.run(DemoApplication.class, args);
        PlayerService playerService = new PlayerService();
        playerService.findPlayerById(1);
    }

Would really appreciate help with this because I'm quite honestly stuck.

code_mechanic
  • 1,097
  • 10
  • 16
Ace
  • 3
  • 3

2 Answers2

0

You have to use Optional to find out if there is a null value corresponding to any player id. You can follow the below syntax.

    public PlayerEntity findPlayerById(long id) {
        Optional<PlayerEntity> result=playerRepository.findById(id);

        PlayerEntity  player=null;
        if(result.isPresent()){
            player=result.get();
        }else{
            throw new RuntimeException("Did not find player id"+id);
        }
        return player;

    }
Nisha Jha
  • 64
  • 3
  • This will not help the repository being null, but as a note you can write this more succinctly as `return repo.findById(id).orElseThrow(new RuntimeException("no such id "+ id))`. – daniu Apr 15 '21 at 11:24
0

The service needs the repository autowired; that only happens if it is created by the Spring context. By creating it in main via new, Spring doesn't get the chance to inject anything into it, so its field remains null.

If you want to use the service, you need to access it from a method that makes sure the context has been properly created. You can do that by using a @PostConstruct method for example.

@SpringBootApplication
public class DemoApplication {
    // usually not held in an application class, but will work
    @Autowired
    private PlayerService service;

    public static void main(String[] args) throws IOException, InterruptedException, JSONException {
        SpringApplication.run(DemoApplication.class, args);
    }
   
  @PostConstruct
  public void doStuff() {
    // the service will have been initialized and wired into the field by now
    service.findPlayerById(1);
  }
daniu
  • 14,137
  • 4
  • 32
  • 53