I have tree of ol and li elements. I am adding this element dynamically. After this I would like to deserialize them into java object. Unfortunatelly I am getting an error:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/derp] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException at com.derp.generic.model.GenericModel.getId(GenericModel.java:28)
I know this is happening cause my new elements dosnt have an id. But this meant to be that way, cause Id is generated on database server. Normally id I will do such A think (create object assign parameters throught setters, but without id) there will be no error. And after persist this new object will got an id.
The same I am trying to achieve here. After correct deserialisation I would like to make persist this object and that will create an Id for him.
But I have to tell my Gson builder to allow null, or to not try set parameter which isnt declared (is null).
Here is my code:
public List<SkeletonElement> toObject(String jsonObject) {
Gson gson = new GsonBuilder()
.serializeNulls()
.registerTypeAdapter(Long.class, new LongTypeAdapter())
.create();
List<SkeletonElement> list = gson.fromJson(jsonObject, new TypeToken<List<SkeletonElement>>(){}.getType());
return list;
}
Custom adapter which should to the trick:
package com.derp.generic.helpers;
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
public class LongTypeAdapter extends TypeAdapter<Long>{
@Override
public Long read(JsonReader reader) throws IOException {
if(reader.peek() == JsonToken.NULL){
reader.nextNull();
return null;
}
String stringValue = reader.nextString();
try{
Long value = Long.valueOf(stringValue);
return value;
}catch(NumberFormatException e){
return null;
}
}
@Override
public void write(JsonWriter writer, Long value) throws IOException {
if (value == null) {
writer.nullValue();
return;
}
writer.value(value);
}
}
Generic model where id is declared:
@MappedSuperclass
public abstract class GenericModel<T extends GenericModel<?>> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public long getId() {return id;}
public void setId(long id) {this.id = id;}
public GenericModel() {
}
public GenericModel(Long id) {
super();
this.id = id;
}
}
And json object with null id object at the end
[
{
"name": "Title1",
"id": "1",
"type": "SkeletonJobElement",
"parent_id": "null",
"children": [
{
"name": "Title11",
"id": "2",
"type": "SkeletonJobElement",
"parent_id": "1",
"children": [
{
"name": "Title111",
"id": "5",
"type": "SkeletonFileElement",
"parent_id": "2",
"children": []
},
{
"name": "Title112",
"id": "6",
"type": "SkeletonFileElement",
"parent_id": "2",
"children": []
}
]
}
]
},
{
"name": "Title2",
"id": "3",
"type": "SkeletonJobElement",
"parent_id": "null",
"children": [
{
"name": "Title21",
"id": "4",
"type": "SkeletonJobElement",
"parent_id": "3",
"children": []
}
]
},
{
"name": "Title3",
"id": "null",
"type": "SkeletonJobElement",
"parent_id": "null",
"children": []
}
]
This method returns a primitive long
. You cannot return a null
from this method.
public long getId() { return id; }
Modify the return type to Long
. The instance variable that this method is returning can be null
, but the method itself cannot.
public Long getId() { return id; }
Do the same with the setter.
public void setId(Long id) { this.id = id; }
You can also check for null
before returning.
public long getId() { id == null ? 0L : id.longValue(); }
If possible change getId to return a Long object rather than a primitive long. The automatic conversion to primitive long causes your null pointer exception.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.