5

Question regarding combination of Jackson/JPA

  1. If there are about 20 entities in current application and I have add Jackson dependency in POM, does it mean all entities are by default ready to convert to JSON object? I saw a sample project seems only class annotated as @JsonIgnored is skipped by JSON. If so, then how can this happen, what is behind such mechanism? how JACKSON handle those entities which don't have any Jackson annotation, by default ignored or not? I've been looking for resources online but not much luck.

  2. If only one of the 20 entities need to be mapped to JSON object, does it mean I have to add @JsonIgnore to all other 19 entities? If not, how Jackson differentiate with entity to work on?

Thanks.

Perception
  • 79,279
  • 19
  • 185
  • 195
Dreamer
  • 7,333
  • 24
  • 99
  • 179

2 Answers2

15

Jackson and JPA don't have anything to do with each other. Jackson is a JSON parsing library and JPA is a persistence framework. Jackson can serialize almost any object - the only requirement being that the object have some kind of recognizable properties (Javabean type properties, or bare fields annotated with @JsonProperty. There is an additional requirement for deserialization, that the target type have a default (no-arg) constructor. So, for example, this is an object that Jackson can serialize:

// Class with a single Javabean property, "name"
class Person {
    private String name;

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

And here is another:

// Class with a single field annotated with @JsonProperty
class Account {
    @JsonProperty("accountNumber")
    private String accountNumber;
}

And here is yet another:

@Entity
public class User {
    @Id
    private Long id;

    @Basic
    private String userName;

    @Basic
    @JsonIgnore
    private String password;

    @Basic
    @JsonIgnore
    private Address address;

    // Constructors, getters, setters
}

The last example shows a JPA entity class - as far as Jackson is concerned it can be serialized just like any other type. But, take note of its fields: when this object is serialized into JSON two of the fields will not be included - 'password' and 'address'. This is because they have been annotated with @JsonIgnore. The @JsonIgnore annotation allows a developer to say 'Hey, its ok to serialize this object, but when you do so don't include these fields in the output'. This exclusion only occurs for the fields of this object, so for example, if you included an Address field in another class, but did not mark the field as ignorable, it would be serialized.

To prevent serialization of a type in all cases, regardless of context, use the @JsonIgnoreType annotation. When used on a type it basically means 'I dont care where this type is used, never serialize it'.

Perception
  • 79,279
  • 19
  • 185
  • 195
  • Very very good explanation. Thank you. One remaining question is, does `JACKSON` auto convert all JPA entities to `JSON` object by default even without explicitly declaration(If not use `@JsonIgnore` and `@JsonIgnoreType`)? If so, is that kind of redundency? I know all JPA entities are all `serializable` even without `JACKSON`, but does it mean there is no extra cost to convert all entities to `JSON`object? – Dreamer Apr 12 '13 at 19:33
  • 2
    Jackson doesn't do anything until you invoke serialization, for example by calling `new ObjectMapper().writeValueToString(new Person();`. In this case a `Person` object would be written out as JSON, along with objects that it refers to (as class variables). As it writes these objects out as JSON, it will ignore fields annotated with `@JsonIgnore`, or types annotated with `@JsonIgnoreType`. Those are the rules. At no time does Jackson say 'oh, theres 50 classes in this package, lets convert them to JSON for the heck of it`. Hope that clears things up some. – Perception Apr 12 '13 at 19:37
  • so JACKSON will not convert them all at once but for an Entity say ClassNoJSON when it (for example) becomes managed then the ObjectMapper start to work? In a word, developer should be careful and supposed to put `@JsonIgnoreType` or `@JsonIgnore` on unnecessary entities or fields for better performance? I just try to clear that I am adding JSON feature to on entity but not at a cost to put extra cost on all entities. – Dreamer Apr 12 '13 at 19:42
  • 1
    @Dreamer - yep thats pretty much correct. Jackson doesn't preprocess classes in any way, so adding or omitting Jackson annotation from a class only controls what happens at runtime. Using `@JsonIgnore` and `@JsonIgnoreType` can reduce the total number of fields/types that need to be serialized for a certain call, which potentially will lead to improved performance (memory and speed) in alot of cases. – Perception Apr 12 '13 at 19:49
1

No, you don't need to add @JsonIgnore on every class and if you had tried you would have gotten a compile error, since you can't put it there. Jackson will only work on objects you give to it, it's no magic.

The Jackson documentation is easily found online, such at its project page on github or on the codehaus website.

Pascal Gélinas
  • 2,744
  • 19
  • 20
  • `Jackson will only work on objects you give to it, it's no magic.` How to `give it` could you be more specific? Thanks for the link but I didn't find much about JPA/Jackson on `JACKSON DOCUMENTATION` – Dreamer Apr 12 '13 at 18:36
  • Hmmmmm, what is your question about then? How to configure JPA (hibernate?) to use Jackson to do serialization? – Pascal Gélinas Apr 12 '13 at 18:46
  • Yes, the question is more like how to configure `Jackson` on JPA, but my confusion is really about how `JACKSON` handle those entities which don't have any Jackson annotation, by default ignored or not? – Dreamer Apr 12 '13 at 18:54