0

I'm using JPA, Jackson and JAX-RS in the following way.

My entity:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {

    @Id
    @GeneratedValue
    private long id;

    private String name;
    private int age;

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}

This class has no setter for id because it's auto generated. Even if I put the setter there is no difference. I don't mind having it if Jackson needs it but it shouldn't be used anyway.

This is the resource:

import java.io.IOException;

import javax.inject.Inject;
import javax.json.JsonObject;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.codehaus.jackson.map.ObjectMapper;

import com.test.persons.entity.Person;

@Path("persons")
public class PersonResource {

    @Inject
    PersonService service;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response save(JsonObject inputPerson) {
        ObjectMapper mapper = new ObjectMapper();
        Person person = null;
        try {
            person = mapper.readValue(inputPerson.toString(), Person.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        service.save(person); // calls @PersistenceContext EntityManager#persist(person)
        return Response.ok(person).build();
    }
}

The problem is that the inputPerson comes with its own id which should be ignored and person should have auto generated its own id. But Jackson uses the id from inputPerson which results in an exception in the JPA layer (because the @Id is wrong).

What I want is just to create a Person object with the properties of the given Person in JsonObject form and with its auto generated id. How can I achieve that?

Note that I when I serialize a Person to Json String with

String s = mapper.writeValueAsString(person);

I do need the id to be serialized. Just not deserialized.

Mark
  • 2,167
  • 4
  • 32
  • 64

1 Answers1

0

You can mark your field id with @JsonIgnore annotation, this way Jackson Json will completely ignore this field.

Upd. If you want to ignore that field when you deserialize object, but use it when you serialize it, @JsonProperty(access = Access.READ_ONLY) could be useful. Or you can try to annotate setter with @JsonIgnore.

AntonBerezin
  • 350
  • 1
  • 5
  • But when I write the Person to JSON format will it also be ignored? I added a note at the end. – Mark May 18 '17 at 13:18
  • Yes, then you can use @JsonProperty(access = Access.READ_ONLY) – AntonBerezin May 18 '17 at 13:22
  • I'm getting errors in Eclipse: `Multiple markers at this line -The attribute access is undefined for the annotation type JsonProperty -WRITE_ONLY cannot be resolved or is not a field` Maybe the version is old? How do I check? I'm using Wildfly 10.1. – Mark May 18 '17 at 13:25
  • What happens when you add @JsonIgnore on setter instead of the field itself? – AntonBerezin May 18 '17 at 13:30
  • Checking. it looks like it's ignoring the id both on read and write. though i understand that since we didn't annotate the getter it shouldn't happen. let me dig a bit. thanks. – Mark May 18 '17 at 13:39
  • Yes. I can confirm id is not being serialized as well. so now deser. works but ser. broke. – Mark May 18 '17 at 13:46
  • Ah, I found the answer here: http://stackoverflow.com/questions/16019834/ignoring-property-when-deserializing. Very unintuitive. No idea why that's what needs to be done. I don't even need the setter at all. – Mark May 18 '17 at 13:49