简体   繁体   English

生成自动Id IdGeneratorStrategy

[英]Generate Automatic Id IdGeneratorStrategy

I'm using Goole App Engine to Build my REST API, I've already marked my class as PersistenceCapable and also i got defined my @PrimaryKey and also marked as @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) , also i've already EndPoints generated. 我正在使用Goole App Engine构建我的REST API,我已经将我的类标记为PersistenceCapable ,并且我已经定义了我的@PrimaryKey并且还标记为@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) ,我也已经使用了EndPoints产生。 but when i type in the terminal window a curl command to insert a new entity or registry it doesn't work. 但是当我在终端窗口中键入一个curl命令来插入一个新的实体或注册表它不起作用。 this is the code: 这是代码:

 @PersistenceCapable(identityType = IdentityType.APPLICATION)
 class Student{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long     id;
    private String   studentName;
    ....
    ....
    ....
}

this is the curl command and response from my local server. 这是来自我本地服务器的curl命令和响应。 when i try to insert a new entity 当我尝试插入一个新实体

curl -H 'Content-Type: application/json' -d'{"studentName": "myname"}' htto://localhost:8889/_ah/api/utp/v1/student

and this is the response from the local server. 这是本地服务器的响应。

"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."

i've been thinking that id was automatically generated an inserted. 我一直以为id是自动生成插入的。 but that isn't happening here. 但这不会发生在这里。 Unlike of insert an id together 与将id插入在一起不同


  1. are my class wrong? 我的班错了?
  2. are my POST/json request Ok? 我的POST / json请求好吗?

Thanks in advance. 提前致谢。

I think the that i've found the solution. 我认为我找到了解决方案。 It seems that every endpoint generated by Google App Engine(GAE) framework has a simple method which check every time that someone is trying to insert or update and a persistant instance, so the fact was every time that i've tried to insert a new student using curl/json without specify de new id for the instance it displayed a error message like this one: 似乎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.

so i've solve the problem editing my endpoint class by checking if the new object(sent by curl command and wrapped json format) has a not null id value before even check if the object has been stored before with this code: 所以我通过检查新对象(由curl命令和包装的json格式发送)是否具有非null id值来解决编辑我的端点类的问题,甚至在检查该对象之前是否已存储此代码:

        if(student.getKey() != null){
            if (containsStudent(student)) {
                throw new EntityExistsException("Object already exists");
            }
        }
        mgr.makePersistent(student);

As far i haven't seen any documentation which can clarify that aspect for me. 到目前为止,我还没有看到任何可以为我澄清这方面的文档。 Also i add, i've spend a lot of time reading the documentation on GAE before trying to figure out what's been happening. 另外,我补充说,我花了很多时间阅读GAE上的文档,然后才弄清楚发生了什么。


All that made me think that maybe just maybe the GAE documentation is not up to date or probably i havent search enough, so if someone know about. 所有这些让我觉得也许只是GAE文档可能不是最新的,或者我可能没有足够的搜索,所以如果有人知道。 please let me know it and grow the common knowledge. 请让我知道并增长常识。 thanks @DataNucleus. 谢谢@DataNucleus。

NOTE: "This fork that i've made should not be taked as correct answer, it could be take you to unexpected behavior of your app." 注意: “我做的这个分叉不应该被视为正确的答案,它可能会带你到应用程序的意外行为。”

The problem lies in the contains method of the endpoint that was generated automatically. 问题在于自动生成的端点的contains方法。 The exception being thrown is javax.jdo.JDOFatalInternalException when the id is null and the method catches the exception javax.jdo.JDOObjectNotFoundException. 当id为null并且该方法捕获异常javax.jdo.JDOObjectNotFoundException时,抛出的异常是javax.jdo.JDOFatalInternalException。

The exception is never caught and you get the error. 从未捕获到异常并且您收到错误。 I don't if it's a bug or what, but after updating the catch statement to catch both, the problem was solved. 我不知道如果它是一个bug或什么,但在更新catch语句以捕获两者之后,问题就解决了。

Hope it helps! 希望能帮助到你!

As remarked in the answer by AlexSanchez, the generated endpoint code expects the primary key already set on inserting new identities. 正如AlexSanchez在回答中所述,生成的端点代码需要在插入新身份时设置主键。

While some may view this as a bug, others may view as a feature, because it requires the client to generate the key somehow (eg by creating a random uuid when the key type is String). 虽然有些人可能将此视为一个错误,但其他人可能会将其视为一个功能,因为它需要客户端以某种方式生成密钥(例如,当密钥类型为String时创建随机uuid)。 This way, the client can create a full graph of entities even while offline and upload them to the server once online. 这样,客户端即使在离线状态下也可以创建实体的完整图表,并在线后将其上传到服务器。

(I think the Spine framework is an example for this idea: http://spinejs.com/ .) (我认为Spine框架就是这个想法的一个例子: http//spinejs.com/ 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM