@JsonIgnore vs @Transient -difference?

We should distinguish between javax.persistence.Transient and java.beans.Transient. As mentioned by @shazin and @Abhishek Kumar, the former signals JPA to ignore the property for persistence and does not affect marshalling. Jackson treats the latter the same as JsonIgnore during marshalling, as can be seen in JacksonAnnotationIntrospector#_isIgnorable(Annotated):

protected boolean _isIgnorable(Annotated a)
{
    JsonIgnore ann = _findAnnotation(a, JsonIgnore.class);
    if (ann != null) {
        return ann.value();
    }
    if (_java7Helper != null) {
        Boolean b = _java7Helper.findTransient(a);
        if (b != null) {
            return b.booleanValue();
        }
    }
    return false;
}

where Java7SupportImpl#findTransient(Annotated) is looking for java.beans.Transient.


The clear difference between the two is that @Transient is used as part of JPA to ignore a field from persisting if it is marked as @Transient.

Where as @JsonIgnore is only used to Ignore a marked field from being serialized, de-serialized to and from JSON.

Which means a field marked as @JsonIgnore can still be persisted in a JPA persistence where as a field marked @Transient will neither be persisted nor be serialized, de-serialized.


@Transient is an allegory to transient keyword in Java language. When used with a variable, it is never serialized.

Example:

public class Person {
    String name;
    int age;
    String password;

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

    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;
    }

    @Transient
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

public void serializationTest() throws JsonProcessingException {

    Person aPerson = new Person("Demonte", 37, "bestKeptSecret1995");
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(aPerson);

    System.out.println(json);
}

By annotating getPassword() (remember getters for serialization) @Transient will produce

{"name":"Demonte","age":37}

Now if you revisit the Person class code and remove @Transient and add transient to the password variable and also add a feature to the Jackson mapper to tell it how to handle fields marked as transient

transient String password;

and

mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);

(remember Jackson uses getters not members directly for serialization) then you will get the same output.