在Play应用程序中使用ModelCompanion的fromJSON方法会抛出NoSuchMethodException。



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

  • 斯卡拉 2.9.3
  • 玩 2.0.4
  • SalatWithPlay2 1.1

我的conf/routes文件中有这个:

PUT /newVenue   controllers.Application.createNewVenue

我的Application.scala文件中有这个:

def createNewVenue = Action(parse.json) { request =>
    val newVenue = Venue.fromJSON(request.body.toString)
    Venue.insert(newVenue)
    Ok("New Venue Created")
  }

这是Venue.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)

为了测试这是否有效,我发送了一个 PUT 请求来localhost:9000/newVenue将此 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]

我认为触发错误的行是val newVenue = Venue.fromJSON(request.body.toString)。

有谁知道出了什么问题?我遵循了SalatWithPlay2页面中的教程,并在类似问题中遵循了一些建议),但到目前为止我没有运气。

更新:

我找到了一个解决方法,虽然它不完全是一个解决方案,但也许它对其他人和理解实际解决方案有所帮助。

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

case class Venue(
        val venueId:ObjectId,
        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:Long,
        var playlist:Playlist, 
        var isPlaying:Boolean = false) 

而且我没有错误!

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

谢谢!

只是在黑暗中射击,但您可以尝试将对象类命名为其他名称吗?也许去VenueCompanion?编译器似乎可能对要应用于哪个对象感到困惑。IE 它不适用于您想要的案例类场地。我很好奇之后的异常是否仍然相同。

所以我找到了问题所在。

在请求正文中发送的 JSON 属性必须与 mongodb 文档的属性名称匹配,而不是与 Scala 对象的属性匹配。

因此,如果我的班级场地是这样定义的: 案例类 地点( @Key("_id") val venueId:ObjectId, var 播放列表:播放列表, var 正在播放:布尔值 = 假)

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

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

不:

{"venueId": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}

相关内容

  • 没有找到相关文章

最新更新