1
votes

Error:

2021-10-13 12:25:27.092 ERROR 21016 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause

Stack Trace (many repetitions of):

java.lang.StackOverflowError: null
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.createCollection(MappingMongoConverter.java:731) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:646) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeProperties(MappingMongoConverter.java:620) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:596) ~[spring-data-mongodb-3.1.5.jar:3.1.5]

Also, I doubt this is significant, but the stack traces appear to be unrelated to each other, as in none of the methods call each other. I haven't spend a lot of time going through third party libraries, but that seems weird to me.

Anyway, it seems like I am attempting a standard save and the exception I get is not informative. Here is the POJO that causes the crash upon save():

public class GameEntity {
     @Id
     @Indexed(unique = true)
     private long id;
     private List<Player> players;
     private List<Card> cards;
     private List<Card> riverCards;
     private boolean isBet;
     private boolean isDealDone;
     private BetManagerEntity betManagerEntity;

     private int desiredNumberOfPlayers;
     private int openSlots;
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date createdAt;
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date updatedAt;

//getters and setters
}

And here is the nested object:

public class BetManagerEntity {
     private int bigBlind;
     private int smallBlind;
     private int turnNumber;
     private int turnsLeftInRound;
     private List<Player> activeBetters;
     private int pot = 0;
     private int betAmount;
     private int bigBlindTurn = -1;
     private List<Bet> bets;
     private List<String> betMessages;
     private Integer maxBet;

//getters and setters

The only thing I could think of was that maybe BetManagerEntity also needed an @Id of its own, so I tried adding that and got a slightly different error:

OpenJDK 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryAcquireShared(I)I [1]
OpenJDK 64-Bit Server VM warning: Potentially dangerous stack overflow in ReservedStackAccess annotated method java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(I)Z [1]
2021-10-13 12:42:54.845 ERROR 29272 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause

and

java.lang.StackOverflowError: null
    at java.base/java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(ReentrantReadWriteLock.java:427) ~[na:na]
    at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1382) ~[na:na]
    at java.base/java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(ReentrantReadWriteLock.java:897) ~[na:na]
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:239) ~[spring-data-commons-2.4.5.jar:2.4.5]
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:201) ~[spring-data-commons-2.4.5.jar:2.4.5]
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:87) ~[spring-data-commons-2.4.5.jar:2.4.5]
    at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:73) ~[spring-data-commons-2.4.5.jar:2.4.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:568) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeCollectionInternal(MappingMongoConverter.java:821) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.createCollection(MappingMongoConverter.java:736) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:646) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeProperties(MappingMongoConverter.java:620) ~[spring-data-mongodb-3.1.5.jar:3.1.5]
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:596) ~[spring-data-mongodb-3.1.5.jar:3.1.5]

I then removed the @Id for BetManagerEntity so that it was back to how it originally was, but I still get the new stack trace when I attempt to save GameEntity

My repository is simple:

package com.brewster.poker.repository;

import com.brewster.poker.model.GameEntity;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface GameRepository extends MongoRepository<GameEntity, Long> {
}

There is a lot going on with the rest of my code. I made a functional Texas Hold Em game and then refactored to allow my app to be able to run multiple games at once, and I also switched my database to MongoDB.

I don't think my Service class will help much, but here is the method that causes the error:

public NewGameResponse startNewDeal(GameEntity gameEntity, UserDto userDto){
     LOGGER.info("starting new deal with {}", userDto);
     List<Card> cards = getNewStandardDeck();

     dealPlayerCards(gameEntity.getPlayers(), cards);
     gameEntity.applyNewDeal(cards);

     betService.startNewDeal(gameEntity);
     LOGGER.info("hustling {}", gameEntity);

     GameEntity savedGame = gameRepository.save(gameEntity); //throws error

     return getNewGameResponse(savedGame, userDto);
}

here is the log that shows the gameEntity before I attempt to save it

2021-10-13 12:52:21.718 INFO 26968 --- [nio-8080-exec-2] c.b.poker.service.TexasHoldEmService : hustling GameEntity{id=0, players=[com.brewster.poker.player.ComputerPlayer@9474326, com.brewster.poker.player.ComputerPlayer@12509617, com.brewster.poker.player.ComputerPlayer@469127f7, com.brewster.poker.player.HumanPlayer@6e84c90f], cards=[King of Diamonds, Six of Clubs, Four of Hearts, Queen of Hearts, Five of Hearts, Queen of Diamonds, Nine of Diamonds, Three of Hearts, Seven of Hearts, Ten of Hearts, Four of Spades, Ten of Spades, Ten of Clubs, Nine of Hearts, Five of Clubs, Jack of Spades, Two of Spades, Six of Hearts, Six of Diamonds, Eight of Clubs, Two of Hearts, Seven of Spades, Five of Spades, Ten of Diamonds, Three of Clubs, Two of Diamonds, Ace of Spades, Nine of Clubs, King of Clubs, Five of Diamonds, Queen of Spades, Ace of Hearts, Seven of Diamonds, Four of Diamonds, Four of Clubs, Seven of Clubs, Three of Spades, Eight of Diamonds, Nine of Spades, Eight of Hearts, Queen of Clubs, Three of Diamonds, Jack of Diamonds, Ace of Diamonds], riverCards=[], isBet=true, isDealDone=false, BetManagerEntity{ bigBlind=5, smallBlind=0, turnNumber=0, turnsLeftInRound=4, activeBetters=[com.brewster.poker.player.ComputerPlayer@9474326, com.brewster.poker.player.ComputerPlayer@12509617, com.brewster.poker.player.ComputerPlayer@469127f7, com.brewster.poker.player.HumanPlayer@6e84c90f], pot=10, betAmount=5, bigBlindTurn=0, bets=[com.brewster.poker.bet.BlindAction@43eaeee0], betMessages=[HAL212 posts the $5 blind], maxBet=2147483647}, desiredNumberOfPlayers=4}

1
Can you show us how you try to save.. Better remove unwated fields, but need to know about the Repository and service and annotationsvarman
It's very standard so I don't think it will help but donedbrewster
it does look a bit odd. What happens if you remove all fields but the id from GameEntity and try to save that?Chris Turner

1 Answers

0
votes

Make sure you don't have cyclic (loop) dependencies between your entities. (For instance entity Player has a reference to a Bet and a Bet to a Player).