我是Scala的新手,我正在尝试使用我的第一个Play 2.0应用程序。我正在使用:
我在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页面中的教程进行了操作,并遵循similar problems中的一些建议,但到目前为止我没有运气。
更新:
我找到了一种解决方法,虽然它不是一个完全解决方案,但它可能对其他人有用,也可以了解实际的解决方案。
如果删除注释@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实例。
谢谢!
答案 0 :(得分:0)
只是在黑暗中拍摄,但你能尝试将你的对象类命名为其他东西吗?也许是VenueCompanion?似乎编译器可能会对要应用的对象感到困惑。 IE它不适用于你想要的案例类Venue。如果之后例外情况仍然相同,我很好奇。
答案 1 :(得分:0)
所以我发现了什么问题。
请求正文中发送的Json的属性必须与mongodb文档的属性名称匹配,而不是Scala对象的属性。
所以如果我的班级Venue定义如下: 案例类别地点( @Key(“_ id”)val venueId:ObjectId, var播放列表:播放列表, var isPlaying:Boolean = false)
我必须在PUT请求中发送的Json是:
{"_id": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}
不:
{"venueId": 3,"playlist":{"playlistId":2,"currentSongPosition":5},"isPlaying":false}