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. but when i type in the terminal window a curl command to insert a new entity or registry it doesn't work. 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. 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. but that isn't happening here. Unlike of insert an id together
Thanks in advance.
There are basically 4 strategies to generate values of id fields. These are AUTO , IDENTITY , SEQUENCE and TABLE . * Defines the types of primary key generation strategies. * database table to ensure uniqueness.
GenerationType. AUTO This GenerationType indicates that the persistence provider should automatically pick an appropriate strategy for the particular database. This is the default GenerationType, i.e. if we just use @GeneratedValue annotation then this value of GenerationType will be used.
AUTO: Hibernate selects the generation strategy based on the used dialect, IDENTITY: Hibernate relies on an auto-incremented database column to generate the primary key, SEQUENCE: Hibernate requests the primary key value from a database sequence, TABLE: Hibernate uses a database table to simulate a sequence.
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:
"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:
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.
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. please let me know it and grow the common knowledge. thanks @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. The exception being thrown is javax.jdo.JDOFatalInternalException when the id is null and the method catches the exception javax.jdo.JDOObjectNotFoundException.
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.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With