Reputation: 5624
I have two entities X and Y with the relation @ManyToMany. X has a list of Y's, let's call it yList. Both X and Y has other class members as well (they are not important).
I am using Hibernate as JPA provider, and jackson-databind / jackson-annotations for things like serialization and deserialization.
Now, the following json is received from the client. It has all the fields of X, but only a list of id's for Y. As a concrete example, X could be Person and Y could be Country. And the many-to-many relation captures which countries have been visited by whom.
{
name: 'Bob Dylan',
age: '74',
visitedCountryIds: ['45', '23', '85']
}
When deserializing this json, I want to populate all the fields of the entity X, including yList, such that the elements of yList are resolved by looking up these entities in the database.
My idea so far is to deserialize yList by writing a custom subclass of JsonDeserializer, and have it perform the lookup by id.
Is this a reasonable approach?
Upvotes: 1
Views: 1107
Reputation: 23552
You could use @JsonCreator
(as already suggested by Uri Shalit) or just a setter method for your property in which you would do necessary lookups from the database.
However, if you have many entities (and associations) for which you want to do this, then this could be a repeated boilerplate code. Also, if implemented in entity classes directly, it would pollute them with database lookup code (readability, SRP, etc).
If you want some generic approach to this, then I think you are on a good way; custom deserializer is the place to implement it.
If I were to implement the generic approach, I would probably introduce a custom annotation which I would place on the association definition together with standard JPA annotations. For example:
@MyCustomJsonIds("visitedCountryIds")
@ManyToMany(...)
private List<Country> countries;
Then, in the deserializer, I would query for the presence of those annotations to dynamically determine what needs to be looked up from the database.
Upvotes: 2
Reputation: 2318
Another option is to create a constructor that that accepts those parameters, annotate it with @JsonCreator
and have the constructor perform the lookup from the database, this way you don't need to write a specific deserializer.
Upvotes: 2