playframework - Play Morphia MappingException In WebSocket Iteratee After Reload -
i'm using play 2.3 , akka set simple publish subscribe protocol on web socket. part of protocol, after client subscribes, server sends initial state database.
my current code works but, during development, morphia query inside socket iteratee stops working after development reload. regular requests, requests make exact same query, continue work fine.
i'm using distributed pub sub mediator akka plugin. here's relevant code actor representing web socket listener:
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(...) } }
and main view controller:
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 morphia val current = myobj.findbyname(target) // notify of current state ws ! statusupdate(target, current) // subscribe further updates mediator ! distributedpubsubmediator.subscribe(target, ws) } } (in, out) } }
the problem occurs in query statement in iterattee. after reload, morphia throws org.mongodb.morphia.mapping.mappingexception: not map models.myobj id: 5507a3653004b8a9e8f3d3b2
. here's full trace:
org.mongodb.morphia.mapping.mappingexception: not map models.myobj id: 5507a3653004b8a9e8f3d3b2 @ org.mongodb.morphia.mapping.mapper.fromdb(mapper.java:594) @ org.mongodb.morphia.mapping.mapper.fromdbobject(mapper.java:299) @ org.mongodb.morphia.query.morphiaiterator.convertitem(morphiaiterator.java:79) @ org.mongodb.morphia.query.morphiaiterator.processitem(morphiaiterator.java:65) @ org.mongodb.morphia.query.morphiaiterator.next(morphiaiterator.java:60) @ org.mongodb.morphia.query.queryimpl.get(queryimpl.java:402) @ models.myobj$.findbyname(myobj.scala:99) @ controllers.myobj$$anonfun$myobj$1$$anonfun$4.apply(myobj.scala:99) @ controllers.myobj$$anonfun$myobj$1$$anonfun$4.apply(myobj.scala:93) @ play.api.libs.iteratee.iteratee$$anonfun$foreach$1.apply(iteratee.scala:201) @ play.api.libs.iteratee.iteratee$$anonfun$foreach$1.apply(iteratee.scala:201) @ play.api.libs.iteratee.iteratee$$anonfun$fold$1$$anonfun$apply$1.apply(iteratee.scala:41) @ play.api.libs.iteratee.internal$.eagerfuture(package.scala:30) @ play.api.libs.iteratee.iteratee$$anonfun$fold$1.apply(iteratee.scala:41) @ play.api.libs.iteratee.iteratee$$anonfun$fold$1.apply(iteratee.scala:41) @ play.api.libs.iteratee.iteratee$$anonfun$1.apply(iteratee.scala:60) @ play.api.libs.iteratee.iteratee$$anonfun$1.apply(iteratee.scala:60) @ scala.concurrent.impl.future$promisecompletingrunnable.liftedtree1$1(future.scala:24) @ scala.concurrent.impl.future$promisecompletingrunnable.run(future.scala:24) @ akka.dispatch.taskinvocation.run(abstractdispatcher.scala:41) @ akka.dispatch.forkjoinexecutorconfigurator$akkaforkjointask.exec(abstractdispatcher.scala:393) @ scala.concurrent.forkjoin.forkjointask.doexec(forkjointask.java:260) @ scala.concurrent.forkjoin.forkjoinpool$workqueue.runtask(forkjoinpool.java:1339) @ scala.concurrent.forkjoin.forkjoinpool.runworker(forkjoinpool.java:1979) @ scala.concurrent.forkjoin.forkjoinworkerthread.run(forkjoinworkerthread.java:107) caused by: org.mongodb.morphia.mapping.mappingexception: error setting value converter (objectidconverter) models.myobj.id 5507a3653004b8a9e8f3d3b2 @ org.mongodb.morphia.converters.defaultconverters.fromdbobject(defaultconverters.java:137) @ org.mongodb.morphia.mapping.valuemapper.fromdbobject(valuemapper.java:27) @ org.mongodb.morphia.mapping.mapper.readmappedfield(mapper.java:608) @ 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 models.myobj @ sun.reflect.unsafefieldaccessorimpl.throwsetillegalargumentexception(unsafefieldaccessorimpl.java:167) @ sun.reflect.unsafefieldaccessorimpl.throwsetillegalargumentexception(unsafefieldaccessorimpl.java:171) @ sun.reflect.unsafefieldaccessorimpl.ensureobj(unsafefieldaccessorimpl.java:58) @ sun.reflect.unsafeobjectfieldaccessorimpl.set(unsafeobjectfieldaccessorimpl.java:75) @ java.lang.reflect.field.set(field.java:758) @ org.mongodb.morphia.mapping.mappedfield.setfieldvalue(mappedfield.java:508) @ org.mongodb.morphia.converters.defaultconverters.fromdbobject(defaultconverters.java:135) ... 27 more
this exception happens in web socket handler, regular request can make query fine. restarting development server fixes problem until next reload.
here's console logs startup , 1 restart: http://pastebin.com/xsstw4ki
any thoughts on may going on here? other references found error seem unrelated or old.
update - july 4, 2015
happens on play 2.4.2 well.
you can use following code snippet resolve this. modify morphia creation adding following code (scala code)
if (play.isdev) morphia.getmapper.getoptions.setobjectfactory(new playcreator)
the definition playcreator class (java code)
public class playcreator extends defaultcreator { @override protected classloader getclassloaderforclass() { return play.application().classloader(); } }
please add relevant imports , hot reload should work great :)
Comments
Post a Comment