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