2009年8月24日月曜日

削除機能の追加

GoogleAppEngineを久々にいじってみた。
今回は、地図から検索のアプリケーションにようやく削除機能を追加した。

削除機能は、自分が登録したデータに関しては、削除、他人が登録したデータに関しては、
削除リクエストの送信と言うような仕様にしております。

今回苦戦したのは、getObjectByIdを利用してデータを取得する部分。

ローカルのサーバでやるとうまく動作するのだけど、AppEngine上では、
どうしてもうまくいかない。

getObjectByIdでnullが返ってきてしまうようである。


08-23 06:20PM 52.000 /loarsh/greet 500 34ms 30cpu_ms 12api_cpu_ms 0kb Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729),gzip(gfe)
See details
125.52.110.203 - takes90 [23/Aug/2009:18:20:52 -0700] "POST /loarsh/greet HTTP/1.1" 500 113 "http://loarsh.appspot.com/loarsh/333D62B7647DD593777255D4248D6999.cache.html" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729),gzip(gfe)" "loarsh.appspot.com"W 08-23 06:20PM 52.006
com.appspot.loarsh.server.GreetingServiceImpl deleteData: key2
E 08-23 06:20PM 52.029
javax.servlet.ServletContext log: Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.lang.Integer com.appspot.loarsh.client.GreetingService.deleteData(long)' threw an unexpected exception: java.lang.NullPointerException
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:360)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:546)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:313)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:139)
at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4823)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4821)
at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359)
at com.google.net.rpc.impl.Server$2.run(Server.java:820)
at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:516)
at com.google.net.rpc.impl.Server.startRpc(Server.java:775)
at com.google.net.rpc.impl.Server.processRequest(Server.java:348)
at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:436)
at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
at com.google.net.async.Connection.handleReadEvent(Connection.java:428)
at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:762)
at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101)
at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:374)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at com.appspot.loarsh.server.GreetingServiceImpl.deleteData(GreetingServiceImpl.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_$3.run(Method_.java:149)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.privilegedInvoke(Method_.java:147)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke(Method_.java:120)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
... 43 more



下記のようにKeyの定義がLongだとうまくいかないので、
Keyに変えてやってみる。

// @PrimaryKey
// @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
// private Long id;

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;

その際に、一緒にKey→longの変換

key.getId()

long →からKeyへの変換

Key k = KeyFactory.createKey(MapData.class.getSimpleName(), key);

を行ってやってみてもうまくいかない。

しかし、いろいろ動作させているうちに本日登録したデータに関しては、
うまく動作することがわかった。

もしかすると、昔登録したデータに関しては、正しく動作しないのだろうか。

内部的になんか変わったりしているのかもしれないということで
納得することにする。

ちなみに今回追加したAppEngine側のコードはこんな感じです。
登録ユーザと、現在のユーザを比較して、処理を切り分けております。

public Integer deleteData(long key){
Integer ret =null;
PersistenceManager pm = PMF.get().getPersistenceManager();
try{
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
Key k = KeyFactory.createKey(MapData.class.getSimpleName(), key);
MapData md = pm.getObjectById(MapData.class,k);
if (md.getAuthor().equals(user)){
pm.deletePersistent(md);
ret = new Integer(0);
}else{
md.addDownVote();
ret = new Integer(1);
}
}finally{
pm.close();
}
return ret;
}


0 件のコメント: