我正在使用Goole App Engine构建我的REST API,我已经将我的类标记为 PersistenceCapable ,并且我已经定义了我的 @PrimaryKey 并且还标记了作为 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY),我也已经生成了EndPoints。但是当我在终端窗口中键入一个curl命令来插入一个新的实体或注册表它不起作用。这是代码:
@PersistenceCapable(identityType = IdentityType.APPLICATION)
class Student{
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
private String studentName;
....
....
....
}
这是来自我本地服务器的curl命令和响应。当我尝试插入新实体时
curl -H 'Content-Type: application/json' -d'{"studentName": "myname"}' htto://localhost:8889/_ah/api/utp/v1/student
这是本地服务器的响应。
"error" : {
"message" : "javax.jdo.JDOFatalInternalException: El valor de llave dado para construir una identidad de SingleFieldIdentity de tipo \"class javax.jdo.identity.LongIdentity\" para la clase \"class com.alex.wserver.Student\" es nulo.\nNestedThrowables:\norg.datanucleus.exceptions.NucleusException: El valor de llave dado para construir una identidad de SingleFieldIdentity de tipo \"class javax.jdo.identity.LongIdentity\" para la clase \"class com.alex.wserver.Student\" es nulo."
我一直以为id是自动生成插入的。但这不会发生在这里。与将id一起插入
不同提前致谢。
答案 0 :(得分:8)
我认为我找到了解决方案。似乎Google App Engine(GAE)框架生成的每个端点都有一个简单的方法,可以在每次有人尝试插入或更新时检查一个持久性实例,所以事实是每次我尝试插入一个新的学生使用curl / json而没有为实例指定de new id它显示如下错误消息:
"error": {
"message": javax.jdo.JDOFatalInternalException: The key value passed to construct a
SingleFieldIdentity type \ class javax.jdo.identity.LongIdentity \ for class \ class com.alex.wserver.Student \ is null. \ nNestedThrowables: \ norg.datanucleus.exceptions.NucleusException: the key value passed to construct a SingleFieldIdentity type \ class javax.jdo.identity.LongIdentity \ for class \ class com.alex . wserver.Student \ is null.
所以我通过检查新对象(由curl命令和包装的json格式发送)是否具有非null id值来解决编辑我的端点类的问题,甚至在使用此代码检查对象是否已经存储之前:
if(student.getKey() != null){
if (containsStudent(student)) {
throw new EntityExistsException("Object already exists");
}
}
mgr.makePersistent(student);
到目前为止,我还没有看到任何可以为我澄清这方面的文件。另外,我补充说,我花了很多时间阅读GAE上的文档,然后才弄清楚发生了什么。
所有这些让我觉得可能只是GAE文档可能不是最新的,或者我可能没有足够的搜索,所以如果有人知道。请让我知道并增长常识。谢谢@DataNucleus。
注意:“我做的这个分叉不应该被视为正确的答案,它可能会让你意外的应用行为。”
答案 1 :(得分:1)
问题在于自动生成的端点的contains方法。当id为null并且该方法捕获异常javax.jdo.JDOObjectNotFoundException时,抛出的异常是javax.jdo.JDOFatalInternalException。
异常永远不会被捕获并且您收到错误。我不知道如果它是一个错误或什么,但在更新catch语句以捕获两者之后,问题就解决了。
希望它有所帮助!
答案 2 :(得分:0)
正如AlexSanchez的回答所述,生成的端点代码需要在插入新身份时设置主键。
虽然有些人可能会将此视为错误,但其他人可能会将其视为一项功能,因为它需要客户端以某种方式生成密钥(例如,当密钥类型为String时创建随机uuid)。这样,客户端即使在离线状态下也可以创建实体的完整图表,并在线上传到服务器。
(我认为Spine框架就是这个想法的一个例子:http://spinejs.com/。)