Playframework 重新加载后在WebSocket迭代对象中播放Morphia MappingException
我正在使用Play2.3和Akka通过web套接字建立一个简单的发布-订阅协议。作为该协议的一部分,在客户端订阅之后,服务器从数据库发送初始状态 我当前的代码最初可以工作,但在开发过程中,socket Iteratee中的Morphia查询在重新加载开发后停止工作。常规请求,甚至是发出完全相同查询的请求,仍然可以正常工作 我正在使用分布式发布子中介Akka插件。以下是表示web套接字侦听器的参与者的相关代码:Playframework 重新加载后在WebSocket迭代对象中播放Morphia MappingException,playframework,websocket,playframework-2.0,akka,morphia,Playframework,Websocket,Playframework 2.0,Akka,Morphia,我正在使用Play2.3和Akka通过web套接字建立一个简单的发布-订阅协议。作为该协议的一部分,在客户端订阅之后,服务器从数据库发送初始状态 我当前的代码最初可以工作,但在开发过程中,socket Iteratee中的Morphia查询在重新加载开发后停止工作。常规请求,甚至是发出完全相同查询的请求,仍然可以正常工作 我正在使用分布式发布子中介Akka插件。以下是表示web套接字侦听器的参与者的相关代码: object Subscriber { def props(channel: Co
object Subscriber {
def props(channel: Concurrent.Channel[JsValue]): Props = Props(new Subscriber(channel))
}
class Subscriber(channel: Concurrent.Channel[JsValue]) extends Actor {
def receive = {
case StatusUpdate(...) =>
channel.push(...)
}
}
对于主视图控制器:
object SocketController extends Controller {
val mediator = DistributedPubSubExtension.get(Akka.system).mediator
def index = WebSocket.using[JsValue] { implicit request =>
val (out, channel) = Concurrent.broadcast[JsValue]
val ws = Akka.system.actorOf(Subscriber.props(channel))
val in = Iteratee.foreach[JsValue] { msg =>
(msg \ "type").as[String] match {
case "Subscribe" =>
val target = (msg \ "value").as[String]
// Query database with Morphia
val current = MyObj.findByName(target)
// Notify of current state
ws ! StatusUpdate(target, current)
// Subscribe for further updates
mediator ! DistributedPubSubMediator.Subscribe(target, ws)
}
}
(in, out)
}
}
问题出现在iterateTee中的查询语句中。重新加载后,Morphia抛出
org.mongodb.morphia.mapping.MappingException:无法映射ID为5507a3653004b8a9e8f3d3b2的models.MyObj
。以下是完整的跟踪:
org.mongodb.morphia.mapping.MappingException: Could not map models.MyObj with ID: 5507a3653004b8a9e8f3d3b2
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:594)
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:299)
at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:79)
at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:65)
at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:60)
at org.mongodb.morphia.query.QueryImpl.get(QueryImpl.java:402)
at models.MyObj$.findByName(MyObj.scala:99)
at controllers.MyObj$$anonfun$MyObj$1$$anonfun$4.apply(MyObj.scala:99)
at controllers.MyObj$$anonfun$MyObj$1$$anonfun$4.apply(MyObj.scala:93)
at play.api.libs.iteratee.Iteratee$$anonfun$foreach$1.apply(Iteratee.scala:201)
at play.api.libs.iteratee.Iteratee$$anonfun$foreach$1.apply(Iteratee.scala:201)
at play.api.libs.iteratee.Iteratee$$anonfun$fold$1$$anonfun$apply$1.apply(Iteratee.scala:41)
at play.api.libs.iteratee.internal$.eagerFuture(package.scala:30)
at play.api.libs.iteratee.Iteratee$$anonfun$fold$1.apply(Iteratee.scala:41)
at play.api.libs.iteratee.Iteratee$$anonfun$fold$1.apply(Iteratee.scala:41)
at play.api.libs.iteratee.Iteratee$$anonfun$1.apply(Iteratee.scala:60)
at play.api.libs.iteratee.Iteratee$$anonfun$1.apply(Iteratee.scala:60)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.mongodb.morphia.mapping.MappingException: Error setting value from converter (ObjectIdConverter) for models.MyObj.id to 5507a3653004b8a9e8f3d3b2
at org.mongodb.morphia.converters.DefaultConverters.fromDBObject(DefaultConverters.java:137)
at org.mongodb.morphia.mapping.ValueMapper.fromDBObject(ValueMapper.java:27)
at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:608)
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:589)
... 24 more
Caused by: java.lang.IllegalArgumentException: Can not set org.bson.types.ObjectId field models.MyObj.id to models.MyObj
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:758)
at org.mongodb.morphia.mapping.MappedField.setFieldValue(MappedField.java:508)
at org.mongodb.morphia.converters.DefaultConverters.fromDBObject(DefaultConverters.java:135)
... 27 more
此异常仅发生在web套接字处理程序中,常规请求可以使查询正常。完全重新启动开发服务器可以修复问题,直到下次重新加载
以下是从启动到重新启动的控制台日志:
你有什么想法吗?我找到的关于这个错误的其他参考似乎是或
更新日期:2015年7月4日
也发生在第2.4.2节 您可以使用以下代码段来解决此问题。通过添加以下代码(Scala代码)修改morphia创建 PlayCreator类的定义是(Java代码)
请添加相关的导入,您的热重新加载应该可以很好地工作:)对此有任何更新吗?我发布了一个GitHub问题(),随后发布了一个Google Groups条目(),但到目前为止仍然无效。此代码库用于Play 2.4.x。对Play 2.x的其他版本使用相关方法
if (Play.isDev)
morphia.getMapper.getOptions.setObjectFactory(new PlayCreator)
public class PlayCreator extends DefaultCreator {
@Override
protected ClassLoader getClassLoaderForClass() {
return Play.application().classloader();
}
}