Google app engine 使用自动生成的Classendpoint插入方法插入实体时引发Nullpointerexception

Google app engine 使用自动生成的Classendpoint插入方法插入实体时引发Nullpointerexception,google-app-engine,google-cloud-endpoints,Google App Engine,Google Cloud Endpoints,我对使用自动生成的端点类感到困惑。我想使用生成的端点将新对象插入数据存储。但是,一个例外是抛出 fooEndpoint.insertFoo(foo); // throws null pointer exception 我的实体类与此源中的给定示例类似: 这是我的实体: @Entity public class Foo { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Key ID; 以下是

我对使用自动生成的端点类感到困惑。我想使用生成的端点将新对象插入数据存储。但是,一个例外是抛出

fooEndpoint.insertFoo(foo); // throws null pointer exception 
我的实体类与此源中的给定示例类似:

这是我的实体:

@Entity
public class Foo {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Key ID;
以下是堆栈跟踪:

java.lang.NullPointerException
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:318)
at org.datanucleus.api.jpa.JPAEntityManager.find(JPAEntityManager.java:256)
at com.FooEndpoint.containsFoo(FooEndpoint.java:150)
at com.FooEndpoint.insertFoo(FooEndpoint.java:96)
另一方面,我可以在使用EntityManager持久化方法时插入新对象。因为,这不会检查数据存储上是否存在

我希望,classEndpoint插入方法应该保存对象并将自动键分配给ID字段

或者我需要初始化ID字段

下面是自动生成的端点类insertFoo方法

  /**
 * This inserts a new entity into App Engine datastore. If the entity already
 * exists in the datastore, an exception is thrown.
 * It uses HTTP POST method.
 *
 * @param foo the entity to be inserted.
 * @return The inserted entity.
 */
public Foo insertFoo(Foo foo) {
    EntityManager mgr = getEntityManager();
    try {
        if (containsFoo(foo)) {
            throw new EntityExistsException("Object already exists");
        }
        mgr.persist(foo);
    } finally {
        mgr.close();
    }
    return foo;
}
这里是containsFoo方法

    private boolean containsFoo(Foo foo) {
    EntityManager mgr = getEntityManager();
    boolean contains = true;
    try {
        Foo item = mgr.find(Foo.class, foo.getID());  // exception occurs here
        if (item == null) {
            contains = false;
        }
    } finally {
        mgr.close();
    }
    return contains;
}
foo.getID()为空。因为,它是新的对象。我期待着,应用程序引擎会为它创建一个密钥。或者我需要为它显式地创建一个键

Foo类中的其他字段是简单类型,如String和boolean


谢谢你抽出时间

我也有同样的问题。 我将介绍我的工作方法

原始自动生成的端点类相关代码:

private boolean containsFoo(Foo-Foo){
EntityManager mgr=getEntityManager();
布尔包含=真;
试一试{
Foo item=mgr.find(Foo.class,Foo.getID());
如果(项==null){
包含=假;
}
}最后{
经理关闭();
}
返回包含;
}
更改了相关代码,以包含作为参数传递的实体对象的空检查

private boolean containsFoo(Foo-Foo){
EntityManager mgr=getEntityManager();
布尔包含=真;
试一试{
//如果未设置ID,则实体尚不存在。
if(foo.getID()==null)
返回false;
Foo item=mgr.find(Foo.class,Foo.getID());
如果(项==null){
包含=假;
}
}最后{
经理关闭();
}
返回包含;
}

通过这种方式,它将按预期工作,尽管我相信会出现更有经验的答案和解释。

在使用Eclipse插件自动生成云端点(通过选择“Google>生成云端点类”)后,我遇到了同样的问题

按照你的建议,我补充说:

if(foo.getID()==null)//用您自己对象的名称替换foo 返回false

问题解决了

谷歌怎么还没有更新自动生成的代码,因为这肯定是一个经常性的问题


谢谢你的解决方案

能否提供
insertFoo
方法的源代码?您将传递什么作为
foo
?我意识到旧版本的云端点生成器插入方法与新版本不同。因为,旧版本的insert方法在不检查存在性的情况下使对象持久化(contain方法)。但是,新的检查对象是否存在。但是,如果密钥为null,则会引发异常。请问,这种情况是否正常?containsFoo方法使用实体管理器的find()方法,在原始问题的上下文中,该方法采用空ID并崩溃,甚至无法判断数据存储是否包含该实体。我的问题是:如果新实体没有ID,如何检查它们是否存在,需要有效的ID?