我对使用自动生成的端点类感到困惑。我想使用生成的端点将新对象插入数据存储区。但是,抛出一个例外。
fooEndpoint.insertFoo(foo); // throws null pointer exception
我的实体类与此源中的给定示例类似:https://developers.google.com/appengine/docs/java/datastore/jpa/overview.
这是我的实体:
@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 persist方法时,我可以插入新对象。因为,这不会检查数据存储区中是否存在。
我希望,classEndpoint insert方法应该保存对象并将自动键分配给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()为null。因为,它是新的对象。我期待着,app引擎为它创建了一个密钥。或者我需要为它明确创建一个密钥?
Foo类中的其他字段是简单类型,例如String和booleans。
感谢您的时间。
答案 0 :(得分:8)
我有完全相同的问题。 我将介绍我的工作方式。
原始自动生成的Endpoints类相关代码:
private boolean containsFoo(Foo foo) {
EntityManager mgr = getEntityManager();
boolean contains = true;
try {
Foo item = mgr.find(Foo.class, foo.getID());
if (item == null) {
contains = false;
}
} finally {
mgr.close();
}
return contains;
}
更改了相关代码,以包含对作为参数传递的实体对象的空检查。
private boolean containsFoo(Foo foo) {
EntityManager mgr = getEntityManager();
boolean contains = true;
try {
// If no ID was set, the entity doesn't exist yet.
if(foo.getID() == null)
return false;
Foo item = mgr.find(Foo.class, foo.getID());
if (item == null) {
contains = false;
}
} finally {
mgr.close();
}
return contains;
}
这样它会像预期的那样工作,虽然我相信会出现更有经验的答案和解释。
答案 1 :(得分:2)
在使用Eclipse插件自动生成云端点(通过选择“Google> Generate Cloud Endpoint Class”)后,我遇到了同样的问题。
根据您的建议,我补充道:
if(foo.getID()== null)//用您自己对象的名称替换foo 返回false;
问题解决了。
Google如何更新自动生成的代码,因为这必定是一个高度反复出现的问题?
感谢您的解决方案。