#java #mongodb #spring-boot
Вопрос:
Ошибка:
2021-10-13 12:25:27.092 ОШИБКА 21016 — — — [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[DispatcherServlet] : Servlet.service() для сервлета [DispatcherServlet] в контексте с путем [] выдал исключение [Ошибка отправки обработчика; вложенное исключение-java.lang.Ошибка стекирования] с основной причиной
Трассировка стека (много повторений):
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]
Кроме того, я сомневаюсь, что это важно, но трассировки стека, по-видимому, не связаны друг с другом, так как ни в одном из методов не вызываются друг с другом. Я не трачу много времени на просмотр сторонних библиотек, но мне это кажется странным.
В любом случае, похоже, что я пытаюсь выполнить стандартное сохранение, и исключение, которое я получаю, не информативно. Вот POJO, которое вызывает сбой при save()
:
public class GameEntity { @Id @Indexed(unique = true) private long id; private Listlt;Playergt; players; private Listlt;Cardgt; cards; private Listlt;Cardgt; 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 }
А вот вложенный объект:
public class BetManagerEntity { private int bigBlind; private int smallBlind; private int turnNumber; private int turnsLeftInRound; private Listlt;Playergt; activeBetters; private int pot = 0; private int betAmount; private int bigBlindTurn = -1; private Listlt;Betgt; bets; private Listlt;Stringgt; 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 MongoRepositorylt;GameEntity, Longgt; { }
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); Listlt;Cardgt; 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 ИНФОРМАЦИЯ 26968 — [nio-8080-exec-2] c.b.покер.сервис.TexasHoldEmService : азартная игра {id=0, игроки=[com.brewster.poker.Игрок.Компьютерный игрок@9474326, com.брюстер.покер.Игрок.Компьютерный игрок@12509617, com.брюстер.покер.Игрок.Компьютерный игрок@469127f7, com.брюстер.покер.Игрок.Человек-игрок@6e84c90f], карты=[Король Бубен, Шестерка Треф, Четверка Червей, Дама Червей, Пятерка Червей, Дама Бубен, Девятка Бубен, Три Червы, Семь Червей, Десять Червей, Четыре Пики, Десять Пик, Десять Треф, Девятка Червей, Пять Треф, Валет пик, Две Пики, Шесть Червей, Шесть Бубен, Восемь Треф, Две Червы, Семь Пик, Пять Пик, Десять Бубен, Три Трефы, Две Бубны, Туз Пик, Девять Треф, Король Треф, Пять Бубен, Дама пик, Туз Червей, Семь Бубен, Четыре Бубны, Четыре Трефы, Семь Треф, Три Пики, Восемь Бубен, Девять Пик, Восемь Червей, Дама треф, Три Бубны, Валет Бубны, Туз бубен], карты реки=[], isBet=истина, isDealDone=ложь, управление ставками{ bigBlind=5, smallBlind=0, номер поворота=0, поворот влево=4, Активные игроки=[com.brewster.poker.Игрок.Компьютерный игрок@9474326, com.брюстер.покер.Игрок.Компьютерный игрок@12509617, com.брюстер.покер.Игрок.Компьютерный игрок@469127f7, com.брюстер.покер.Игрок.HumanPlayer@6e84c90f], банк=10, количество ставок=5, bigBlindTurn=0, ставки=[com.brewster.poker.bet.BlindAction@43eaeee0], Ставки=[HAL212 размещает блайнд на 5 долларов], maxBet=2147483647}, Желаемое число игроков=4}
Комментарии:
1. Можете ли вы показать нам, как вы пытаетесь сэкономить.. Лучше удалите неочищенные поля, но вам нужно знать о репозитории, сервисе и аннотациях
2. Это очень стандартно, поэтому я не думаю, что это поможет, но сделано
3. это действительно выглядит немного странно. Что произойдет, если вы удалите все поля, кроме
id
«изGameEntity
«, и попытаетесь их сохранить?
Ответ №1:
Убедитесь, что у вас нет циклических (циклических) зависимостей между вашими сущностями. (Например, у Игрока есть ссылка на Ставку, а Ставка на Игрока).