【问题标题】:com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException while implementing One-To-Many bidirectional relationship App Enginecom.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException 同时实现一对多双向关系 App Engine
【发布时间】:2014-03-12 12:51:05
【问题描述】:

我想为我的应用引擎应用程序实现一对多双向关系。以下是我的实体:

@Entity
public class UserMaster {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;
    private String userName;

    @OneToMany(mappedBy = "user")
    List<FeedMaster> feeds;

    getter()...setter() for all properties
}

@Entity
public class FeedMaster {
     @Id
    private String feedId;

    @ManyToOne(fetch = FetchType.LAZY)
    UserMaster user;

   getter()....setter() for both properties
}

在这里,UserMaster 的第一个对象是持久化的,之后当我尝试持久化FeedMaster 的对象时,它会抛出java.io.IOException: com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException 异常。

错误日志:

    Uncaught exception from servlet
java.io.IOException: com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sampleregistrationapp.FeedMaster["user"]->com.sampleregistrationapp.UserMaster["key"]->com.google.appengine.api.datastore.Key["appId"])
    at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAsString(ServletResponseResultWriter.java:187)
    at com.google.api.server.spi.response.ServletResponseResultWriter.write(ServletResponseResultWriter.java:73)
    at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:386)
    at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:124)
    at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:82)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
    at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:188)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)

................................

我搜索了很多,但找不到任何解决方案。我提到了stackoverflow link,但在这里,他们说要删除FeedMasterUserMaster 的getter setter,但如果我删除它,我将无法通过我的UserMaster 对象访问UserMaster 数据。请帮我解决问题。谢谢。

【问题讨论】:

    标签: java android json google-app-engine google-cloud-datastore


    【解决方案1】:

    这里发生的情况是,Jackson 库发现了一个无法转换为 JSON 的循环。在返回这个对象的时候,你必须决定你要在哪里返回关系,在哪里不返回。

    您的代码暗示您可以从UserMaster 访问FeedMaster,从FeedMaster 访问UserMaster。这在您的应用程序级别非常好,但是当您将此对象图序列化为 JSON 时,您必须放弃其中一个关系,因为它会导致 JSON 表示出现无限循环。

    为此,您可以使用@JsonIgnore 注解,如下所示:

    import com.fasterxml.jackson.annotation.JsonIgnore; 
    
    @Entity
    public class FeedMaster {
       @Id
       private String feedId;
    
       @ManyToOne(fetch = FetchType.LAZY)
       UserMaster user;
    
       @JsonIgnore
       public UserMaster getUser() {
          ...
       }
    }
    

    在这种情况下,您的 JSON 将允许您访问来自 UserMaster 的所有 FeedMaster 对象,但不能访问来自 FeedMasterUserMaster 对象。

    【讨论】:

      【解决方案2】:

      您可能已经想到这一点,但一种可能性是您使用“key”作为@Id 的成员字段名称。在过去的几个小时里,我在 appengine 上阅读了大约 4-5 篇不同的教程,并记得在某个地方他们特别指出不要使用“key”这个词作为你的密钥,因为它与内部数据存储 impl 相冲突。 (我最终在这个线程上的方式是我试图找出 JsonMappingException 的另一个问题,所以关于这些错误的资源很少......)

      尝试改变

      private Key key;
      

      private Key k; // obv use a better name such as id for real code (though k may be a reasonable convention in your codebase
      

      看看能不能解决。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-14
        • 1970-01-01
        • 2011-01-15
        相关资源
        最近更新 更多