Надеюсь, вы поможете мне разобраться в этом, пожалуйста. Используя Akka HTTP, Slick и PosgreSQL, я пытаюсь внедрить доску объявлений в качестве упражнения. Вы можете найти последнюю версию в here for a full picture.Переполнение стека для DateTime с использованием спрей-json, Slick и PostgreSQL
Что у меня есть, короче говоря:
У меня есть таблицы, подобные этим:
final class Posts(tag: Tag) extends Table[Post](tag, "POSTS") with CustomColumnTypes {
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def threadId = column[Long]("THREAD_ID")
def secretId = column[String]("SECRET")
def pseudonym = column[String]("PSEUDONYM")
def email = column[String]("EMAIL")
def content = column[String]("CONTENT")
def created = column[DateTime]("CREATED")
final class Threads(tag: Tag) extends Table[Thread](tag, "THREADS") {
def threadId = column[Long]("THREAD_ID", O.PrimaryKey, O.AutoInc)
def subject = column[String]("SUBJECT")
и домен модели:
case class Post(
postId: Option[Long] = None,
threadId: Option[Long],
secretId: String,
pseudonym: String,
email: String,
content: String,
created: DateTime = DateTime.now)
case class Thread(
threadId: Option[Long] = None,
subject: String
case class NewThreadWithPost(
postId: Option[Long] = None,
subject: String,
secretId: String,
pseudonym: String,
email: String,
content: String)
с пользовательским протоколом выписанные например:
trait TextboardJsonProtocol extends DefaultJsonProtocol with SprayJsonSupport with DateTimeHelper {
implicit object DateTimeFormat extends RootJsonFormat[DateTime] {
def read(value: JsValue) = value match {
case dt: JsValue => value.convertTo[DateTime]
case _ => deserializationError("DateTime expected")
}
def write(c: DateTime) = JsString(c.toString)
}
implicit val threadFormat = jsonFormat2(Thread.apply)
implicit val postFormat = jsonFormat7(Post.apply)
implicit val newThread = jsonFormat6(NewThread.apply)
}
и маршруты, как это:
def route: Route = {
...
post {
entity(as[Post]) { post =>
complete(createPost(Some(threadId), post).toJson) }
...
post {
entity(as[NewThread]) { thread =>
(master ? CreateNewThread(thread)).mapTo[NewThread]
complete(StatusCodes.Created) }
...
То, что я намерен делать, и где он не:
Я намерен добавить новую тему и новую запись с помощью этого метода , и он отлично работает:
def createNewThread(nt: NewThread) = {
exec(threads += Thread(None, nt.subject))
exec(posts += Post(None, lastId, secretId, nt.pseudonym, nt.email, nt.content, DateTime.now))
}
Wha т не работает на все это, казалось бы, так метод я использую для создания сообщения:
def createPost(threadId: Option[Long], p: Post) = {
exec(posts returning posts.map(_.secretId)
+= Post(None, p.threadId, secretId, p.pseudonym, p.email, p.content, DateTime.now))
}
Что происходит?
[error] Uncaught error from thread [default-akka.actor.default-dispatcher-7] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[default]
[error] java.lang.StackOverflowError
[error] at main.scala.textboard.TextboardJsonProtocol$DateTimeFromat$.read(Protocol.scala:22)
[info] [ERROR] [SECURITY][12/11/2016 23:03:22.301] [default-akka.actor.default-dispatcher-7] [akka.actor.ActorSystemImpl
(default)] Uncaught error from thread [default-akka.actor.default-dispatcher-7] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled [error] at spray.json.JsValue.convertTo(JsValue.scala:31) <- repeated tens of times
[error] at main.scala.textboard.TextboardJsonProtocol$DateTimeFormat$.read(Protocol.scala:23) <- repeated tens of times
[error] at main.scala.textboard.TextboardJsonProtocol$DateTimeFormat$.read(Protocol.scala:21) <- repeated tens of times
Java.lang.RuntimeException: Nonzero exit code returned from runner: -1 at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code returned from runner: -1
[error] Total time: 18 s, completed 2016-12-11 23:19:16
То, что я уже пытался
- Пытались изолировать причину, по которой это не происходит, когда я использую createNewThread().
- Выполнено с RootJsonFormat [DateTime], чтобы исправить неявный читатель.
- Выполнено с использованием DSL-маршрута, позволяющего использовать или избегать использования актеров.
- Пытался избежать передачи нити в качестве опции.