java - Play 2.1. WebSocket No EntityManager bound to this thread -


i'm trying implement websocket in play 2.1. framework jpa using hibernate , i'm getting following exception when i'm accessing db websocket:

java.lang.runtimeexception: no entitymanager bound thread. try annotate action method @play.db.jpa.transactional @ play.db.jpa.jpa.em(jpa.java:42) @ model.operations.districtoperations.isowner(districtoperations.java:15) @ controllers.security.secured.isownerof(secured.java:28) @ controllers.districtcommunication.initwebsocket(districtcommunication.java:157) @ routes$$anonfun$routes$1$$anonfun$applyorelse$20$$anonfun$apply$20.apply(routes_routing.scala:277) @ routes$$anonfun$routes$1$$anonfun$applyorelse$20$$anonfun$apply$20.apply(routes_routing.scala:277) @ play.core.j.javawebsocket$$anonfun$websocketwrapper$1$$anonfun$apply$1.apply(javawebsocket.scala:20) @ play.core.j.javawebsocket$$anonfun$websocketwrapper$1$$anonfun$apply$1.apply(javawebsocket.scala:14) @ play.core.server.netty.playdefaultupstreamhandler.liftedtree1$1(playdefaultupstreamhandler.scala:324) @ play.core.server.netty.playdefaultupstreamhandler.messagereceived(playdefaultupstreamhandler.scala:322) @ org.jboss.netty.channel.simplechannelupstreamhandler.handleupstream(simplechannelupstreamhandler.java:75) @ org.jboss.netty.channel.defaultchannelpipeline.sendupstream(defaultchannelpipeline.java:565) @ org.jboss.netty.channel.defaultchannelpipeline$defaultchannelhandlercontext.sendupstream(defaultchannelpipeline.java:793) @ org.jboss.netty.handler.codec.http.httpcontentdecoder.messagereceived(httpcontentdecoder.java:104) @ org.jboss.netty.channel.simplechannelupstreamhandler.handleupstream(simplechannelupstreamhandler.java:75) @ org.jboss.netty.channel.defaultchannelpipeline.sendupstream(defaultchannelpipeline.java:565) @ org.jboss.netty.channel.defaultchannelpipeline$defaultchannelhandlercontext.sendupstream(defaultchannelpipeline.java:793) @ org.jboss.netty.channel.channels.firemessagereceived(channels.java:296) @ org.jboss.netty.handler.codec.frame.framedecoder.unfoldandfiremessagereceived(framedecoder.java:455) @ org.jboss.netty.handler.codec.replay.replayingdecoder.calldecode(replayingdecoder.java:538) @ org.jboss.netty.handler.codec.replay.replayingdecoder.messagereceived(replayingdecoder.java:437) @ org.jboss.netty.channel.simplechannelupstreamhandler.handleupstream(simplechannelupstreamhandler.java:75) @ org.jboss.netty.channel.defaultchannelpipeline.sendupstream(defaultchannelpipeline.java:565) @ org.jboss.netty.channel.defaultchannelpipeline.sendupstream(defaultchannelpipeline.java:560) @ org.jboss.netty.channel.channels.firemessagereceived(channels.java:268) @ org.jboss.netty.channel.channels.firemessagereceived(channels.java:255) @ org.jboss.netty.channel.socket.nio.nioworker.read(nioworker.java:84) @ org.jboss.netty.channel.socket.nio.abstractnioworker.processselectedkeys(abstractnioworker.java:472) @ org.jboss.netty.channel.socket.nio.abstractnioworker.run(abstractnioworker.java:333) @ org.jboss.netty.channel.socket.nio.nioworker.run(nioworker.java:35) @ org.jboss.netty.util.threadrenamingrunnable.run(threadrenamingrunnable.java:102) @ org.jboss.netty.util.internal.deadlockproofworker$1.run(deadlockproofworker.java:42) @ java.util.concurrent.threadpoolexecutor$worker.runtask(threadpoolexecutor.java:895) @ java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:918) @ java.lang.thread.run(thread.java:680) 

here code:

@transactional(readonly = true) public static websocket<jsonnode> initwebsocket(final long id) {      if (secured.isownerof(id)) {          return new websocket<jsonnode>() {              // called when websocket handshake done.             public void onready(websocket.in<jsonnode> in,                     websocket.out<jsonnode> out) {                    // each event received on socket,                 in.onmessage(new callback<jsonnode>() {                     public void invoke(jsonnode event) {                           system.out.println(event);                      }                 });                  // when socket closed.                 in.onclose(new callback0() {                     public void invoke() {                          system.out.println("disconnected");                      }                 });                  // send single 'hello!' message                 objectnode on = json.newobject();                 on.put("greeting", "hello");                 out.write(on);             }          };      }else{         return null;     } 

secured isownerof() method:

public static boolean isownerof(long district) {     return districtoperations.isowner(district, context.current().request().username()); } 

and districtoperations.isowner() method:

@transactional(readonly = true) public static boolean isowner(long district, string login){     query query = jpa.em().createquery("select d  district d d.id = :districtid");        district d = (district) query.setparameter("districtid", district).getsingleresult();     return d.getname().equals(login); } 

it's advising me add @transactional annotation have in code, question is: somehow possible access database via entitymanager websocket? because seems me else except entitymanager works fine here.

edit i've tried use entitymanager inside websocket, have still same problem. maybe small reformulation how supposed work database using websocket , jpa? somehow possible use both together?

thank in advance.

in play, websocket not action. @transactional annotation not taken account because play.db.jpa.transactionalaction intercepts action calls.

in case, have manually place code in transaction :

boolean isownerof = jpa.withtransaction(new play.libs.f.function0<boolean>{     public boolean apply() throws throwable {         return secured.isownerof(id);     } }) 

you have same if need access db in other websocket's callbacks. these callbacks executed in other threads , jpa.withtransaction() take care of binding entitymanager these threads.


Comments

Popular posts from this blog

c# - Operator '==' incompatible with operand types 'Guid' and 'Guid' using DynamicExpression.ParseLambda<T, bool> -