spring-boothibernaterepositoryfindby

FindByObject returns null even when record is in the db


In a springboot application I create a Game, with a list-of-cards converted in a large String. The Game is related to a Player.

When I try to lookup the Game for a Player, the Springboot Hibernate app returns NULL . Why??!??

Now I want to create an endpoint to show a players game. I cannot get it working, looking for a solution for days now...

The test I wrote shows the players, with game_ids, but when I try to FindByPlayer, the repository returns: null

The console shows:

=====================1
player = Player [id=234, game=Game [id=232, gameCards=nl.hu.bep2.casino.blackjack.domain.GameCards@c5092df, gameState=playing,  numberOfDecks=1], user=nl.hu.bep2.casino.security.domain.User@1837c802]
=====================2
2023-02-17 18:33:45.333 DEBUG 2216 --- [nio-8080-exec-3] org.hibernate.SQL                        : select game0_.id as id1_2_, game0_.current_move as current_2_2_, game0_.game_cards as game_car3_2_, game0_.game_state as game_sta4_2_, game0_.number_of_decks as number_o5_2_ from game game0_ left outer join player player1_ on game0_.id=player1_.game_id where player1_.id=?
====================3
player =Player [id=234, game=Game [id=232, gameCards=nl.hu.bep2.casino.blackjack.domain.GameCards@c5092df, gameState=playing,  numberOfDecks=1], user=nl.hu.bep2.casino.security.domain.User@1837c802]
speler:   234  heeft geen game

and postman shows:[ null ]

I use the following Classes:

Game

@Transactional
@Entity
@JsonIgnoreProperties({"player","dealer"})
public class Game {
    
    @Id
    @GeneratedValue
    private long id;
     
    @Convert(converter = CardListConverter.class)
    @Column(length = 20000)
    private GameCards gameCards;
    
    @Enumerated(EnumType.STRING)
    private GameState gameState;
  
    @OneToOne(mappedBy="game", cascade = CascadeType.ALL)  
    private Player player;
    
    @OneToOne(mappedBy="game", cascade = CascadeType.ALL)
    private Dealer dealer;
    
    private Move current_move;
    
    private Integer numberOfDecks;
    
    public Game() {
        
    }

Player

@Transactional
@Entity
@JsonIgnoreProperties("game")
public class Player extends Hand implements Serializable{

    @Id
    @GeneratedValue
    private long id;
    //@JsonManagedReference
    @OneToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="game_id")
    private Game game;

    @ManyToOne(fetch = FetchType.EAGER)
    private User user;    // niet via id koppelen aan een object, user heeft de link naar gepersisteerde chips. dit private object wordt in de applicatielaag gevuld met de chips van de user
                            //dependency injection van chips in player in applicatielaag, blackjackservice, startgame

    public Player(){
    }   
    
    public Player(User user, Game game) {
        super();
        this.user = user;
        this.game=game;
        
    }
    

GameRepository

public interface GameRepository  extends JpaRepository<Game, Long>{
    Game findByPlayer(Player player);
}

GamesService

@Service
public class GamesService {
    
    @Autowired
    private GameRepository gameRepository;
    @Autowired
    private UserService userService;
    @Autowired
    private PlayerService playerService;
    
    
    public GamesService(){
    }

    
        public List<Game> GetGamesByUsername(String username) {
        
        List<Game> gameList = new ArrayList<>();
        List<Player> players = this.playerService.GetPlayerByUsername(username); 
        
        for
          ( Player p : players) { 
          System.out.println("=====================1");
          System.out.println("player = "+ p);
          System.out.println("=====================2");
          
          Game game = this.gameRepository.findByPlayer(p);
          gameList.add(game);
          System.out.println("====================3"); System.out.println("player ="+
          p);
          
          if (game != null) { System.out.println("speler:   "+ p.getId() +
          "  /n vinden we game " + game.getId()); }else{
          System.out.println("speler:   "+ p.getId() + "  heeft geen game"); }
              
        }    
        return gameList;        
    }
}

GamesController

@RestController
@RequestMapping("/game")
public class GamesController {
    
    private final GamesService service;
    // SameService injecteren, en service noemen
    public GamesController(GamesService service) {
        this.service = service;
    }
    
    @PostMapping("/showgames")
    @ResponseBody
    public List<Game> getGames(Authentication authentication, UserService userService){
        UserProfile profile = (UserProfile) authentication.getPrincipal();
        
     try {
            List<Game> gameList = new ArrayList<>();
            String username = profile.getUsername();
    
            gameList = this.service.GetGamesByUsername(username);
            
            return gameList;
                
            } catch (NegativeNumberException exception) {
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, exception.getMessage());
            }
    }
}

Also there is a User connected to the player, that works fine Playerservice works fine:

@Service
public class PlayerService {
    
    @Autowired
    private PlayerRepository playerRepository;
    @Autowired
    private UserService userService;


    public List<Player> GetPlayerByUsername(String username) {
        
        User user = userService.loadUserByUsername(username);
        List<Player> players = playerRepository.findByUser(user);        
        
        return players;
    }

Solution

  • If player has game_id, then you may try to reach Game by id as shown below:

    public interface GameRepository extends JpaRepository<Game, Long>{
        Optional<Game> findById(Long id);
    }
    

    Then pass the player.getGameId() to the repository instead of Player.