1

I have a task and a user entity, with a one-to-many relationship. So in english a user can have multiple tasks, and a task belongs to a single user

public class User {
    @Id
    private Long id;

    @OneToMany(mappedBy="task")
    private Set<Task> tasks;
}
public class Task {
    @Id
    private Long id;

    @ManyToOne
    @JoinColumn(name="user_id", nullable=false)
    @JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id")
    @JsonIdentityReference(alwaysAsId=true)
    @JsonProperty("user_id")
    private User user;
    private String name;
}

When i try to POST a task with

{
  "name": "Test task",
  "user_id": 1
}

i get the following:

Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference

EDIT: Following this post and implementing an EntityIdResolver returns in this error:

 Unable to locate persister: java.lang.Object; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unable to locate persister
frisk0k
  • 157
  • 1
  • 1
  • 11
  • 1
    Does this answer your question? [Deserialize JSON with spring : Unresolved forward references Jackson Exception](https://stackoverflow.com/questions/44007188/deserialize-json-with-spring-unresolved-forward-references-jackson-exception) – SternK Mar 24 '20 at 11:24
  • @SternK kinda. Now it throws: Unable to locate persister: java.lang.Object – frisk0k Mar 24 '20 at 11:50

1 Answers1

1

You need to create and bind an object implementing ObjectIdResolver with autowired EntityManager. Jackson is clueless otherwise how to find the correct entity, since there is no relationship between the ORM implementation and de/serialization library in this case.

This resolver itself is:

Definition of API used for resolving actual Java object from Object Identifiers (as annotated using JsonIdentityInfo).

The key method is ObjectIdResolver::resolveId where you get the item to be matched by its ID using the following method:

Sample code:

@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
    return entityManager.find(id.scope, id.key);
}

The resolver shall be used then with @JsonIdentityInfo:

@JsonIdentityInfo(
    generator= ObjectIdGenerators.PropertyGenerator.class, 
    property="id", 
    resolver = CustomIdResolver.class)
...
private User user;

This question might help as well: JsonIdentityInfo Resolver instantiated in Spring Context

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183