使用ModelCompanion';播放应用程序中的s fromJSON方法引发NoSuchMethodException

使用ModelCompanion';播放应用程序中的s fromJSON方法引发NoSuchMethodException,json,scala,playframework,salat,Json,Scala,Playframework,Salat,我是Scala的新手,正在尝试我的第一个Play 2.0应用程序。我正在使用: Scala 2.9.3 播放2.0.4 1.1 我的conf/routes文件中有: PUT /newVenue controllers.Application.createNewVenue def createNewVenue = Action(parse.json) { request => val newVenue = Venue.fromJSON(request.body.toStri

我是Scala的新手,正在尝试我的第一个Play 2.0应用程序。我正在使用:

  • Scala 2.9.3
  • 播放2.0.4
  • 1.1
我的
conf/routes
文件中有:

PUT /newVenue   controllers.Application.createNewVenue
def createNewVenue = Action(parse.json) { request =>
    val newVenue = Venue.fromJSON(request.body.toString)
    Venue.insert(newVenue)
    Ok("New Venue Created")
  }
我的
应用程序.scala
文件中有:

PUT /newVenue   controllers.Application.createNewVenue
def createNewVenue = Action(parse.json) { request =>
    val newVenue = Venue.fromJSON(request.body.toString)
    Venue.insert(newVenue)
    Ok("New Venue Created")
  }
这是
场馆的代码。scala

import play.api.Play.current
import com.novus.salat._
import com.novus.salat.global._
import com.novus.salat.annotations._
import com.novus.salat.dao._
import com.mongodb.casbah.Imports._
import se.radley.plugin.salat._

object Venue extends ModelCompanion[Venue, ObjectId] {
        val collection = mongoCollection("venues")
        val dao = new SalatDAO[Venue, ObjectId](collection = collection) {}
    }

case class Venue(
        @Key("_id") val venueId:ObjectId,
        var playlist:Playlist, 
        var isPlaying:Boolean = false)
为了测试这是否有效,我向
localhost:9000/newVenue
发送一个PUT请求,并将此JSON作为主体:

{"venueId": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}
然后我得到了这个错误:

[error] application - 

! @6d7oco1hf - Internal server error, for request [PUT /newVenue] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[NoSuchMethodException: model.Venue$.apply$default$1()]]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.4]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.4]
    at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor.jar:2.0.2]
    at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.4]
    at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor.jar:2.0.2]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor.jar:2.0.2]
Caused by: java.lang.NoSuchMethodException: model.Venue$.apply$default$1()
    at java.lang.Class.getMethod(Class.java:1605) ~[na:1.6.0_37]
    at com.novus.salat.ConcreteGrater.defaultArg(Grater.scala:350) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater.safeDefault(Grater.scala:360) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater$$anonfun$6$$anonfun$apply$7.apply(Grater.scala:319) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater$$anonfun$6$$anonfun$apply$7.apply(Grater.scala:319) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at scala.Option.orElse(Option.scala:218) ~[scala-library.jar:0.11.3]
{"venueId": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}
我认为触发错误的行是val newVenue=Venue.fromJSON(request.body.toString)

有人知道怎么回事吗? 我遵循了SalatWithPlay2页面中的教程,也遵循了中的一些建议),但到目前为止我没有运气

更新

[error] application - 

! @6d7oco1hf - Internal server error, for request [PUT /newVenue] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[NoSuchMethodException: model.Venue$.apply$default$1()]]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.4]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.4]
    at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor.jar:2.0.2]
    at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.4]
    at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor.jar:2.0.2]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor.jar:2.0.2]
Caused by: java.lang.NoSuchMethodException: model.Venue$.apply$default$1()
    at java.lang.Class.getMethod(Class.java:1605) ~[na:1.6.0_37]
    at com.novus.salat.ConcreteGrater.defaultArg(Grater.scala:350) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater.safeDefault(Grater.scala:360) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater$$anonfun$6$$anonfun$apply$7.apply(Grater.scala:319) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater$$anonfun$6$$anonfun$apply$7.apply(Grater.scala:319) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at scala.Option.orElse(Option.scala:218) ~[scala-library.jar:0.11.3]
{"venueId": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}
我找到了一个解决方法,虽然它不是一个确切的解决方案,但可能对其他人以及理解实际解决方案有帮助

如果我删除注释@Key,case类的代码如下所示:

case class Venue(
        val venueId:ObjectId,
        var playlist:Playlist, 
        var isPlaying:Boolean = false)
case class Venue(
        val venueId:Long,
        var playlist:Playlist, 
        var isPlaying:Boolean = false) 
然后我得到另一个错误:

[RuntimeException: in: unexpected OID input class='net.liftweb.json.JsonAST$JInt', value='3']
例如,如果不使用ObjectId,而是使用Long,则代码如下所示:

case class Venue(
        val venueId:ObjectId,
        var playlist:Playlist, 
        var isPlaying:Boolean = false)
case class Venue(
        val venueId:Long,
        var playlist:Playlist, 
        var isPlaying:Boolean = false) 
我没有错

所以NoSuchMethodException显然与与_id相关的@Key注释有关。我还尝试将venueId重命名为_id,出现了相同的NoSuchMethodException错误。所以问题是:为什么我不能使用@Key注释来说明我的哪些属性映射到mongo数据库中文档的对象id? 除此之外,由于其他原因,常规整数不能自动转换为ObjectId实例


谢谢

这只是一个无中生有的想法,但是你能试着用别的东西来命名你的对象类吗?也许是去维努埃?似乎编译器可能对应用于哪个对象感到困惑。也就是说,它不适用于你想要的案例课堂场地。我很好奇,之后异常是否仍然相同。

因此我找到了问题所在

请求主体中发送的Json属性必须与mongodb文档的属性名称匹配,而不是与Scala对象的属性匹配

因此,如果我的上课地点是这样定义的: 个案课地点( @键(“_id”)val venueId:ObjectId, var播放列表:播放列表, 变量显示:布尔值=假)

我必须在PUT请求中发送的Json是:

{"_id": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}
而不是:

[error] application - 

! @6d7oco1hf - Internal server error, for request [PUT /newVenue] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[NoSuchMethodException: model.Venue$.apply$default$1()]]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.4]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.4]
    at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor.jar:2.0.2]
    at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.4]
    at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor.jar:2.0.2]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor.jar:2.0.2]
Caused by: java.lang.NoSuchMethodException: model.Venue$.apply$default$1()
    at java.lang.Class.getMethod(Class.java:1605) ~[na:1.6.0_37]
    at com.novus.salat.ConcreteGrater.defaultArg(Grater.scala:350) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater.safeDefault(Grater.scala:360) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater$$anonfun$6$$anonfun$apply$7.apply(Grater.scala:319) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at com.novus.salat.ConcreteGrater$$anonfun$6$$anonfun$apply$7.apply(Grater.scala:319) ~[salat-core_2.9.1-1.9.1.jar:1.9.1]
    at scala.Option.orElse(Option.scala:218) ~[scala-library.jar:0.11.3]
{"venueId": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}

谢谢,我尝试了你的建议,得到了完全相同的异常和堆栈跟踪:(我发现另一个问题也有同样的问题,但没有给出答案。这看起来也很相似,但当尝试重新开始播放时,没有发生任何新的情况,我仍然会收到相同的错误。啊,那是因为你使用casbah!抱歉,我没有想到这一点。我非常习惯使用反应式Mongo,你可以通过读取和写入来映射你的对象。)基本上,你可以留下你的“venueId”并让阅读把它映射到“_id”。