Reputation: 3819
I have a question about ORM mapping with Spring JPA.
Consider a simple class Person:
@Entity
public class Person {
@Id
@NotNull
@Column(unique = true, updatable = false, name = "PERSON_ID")
private long personId;
@NotNull
@Size(min = 1)
private String name;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Car> cars;
public Person() {
}
//continue....
and a simple class Car:
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "CAR_ID")
private long carId;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERSON_ID")
private Person person;
@NotNull
@Size(min = 1)
private String typeOfCar;
public Car() {
}
//continue....
Person has a OneToMany relationship with Car.
Recalling that carId is auto-generated, when I POST a new car at the moment I am forced to specify a full Person object (apart from the nullable list of cars):
{
"person": {
"personId": 200,
"name": "Jack"
},
"typeOfCar": "Ferrari"
}
I would like to be able to POST a car object just like this:
{
"person": 200,
"typeOfCar": "Ferrari"
}
thus specifying only the personId (key of the Person entity).
I guess that I need the Person reference in Car to be serialized only as its key and not as the whole object.
How to achieve this?
So far, what I have tried are the following annotations @JsonIdentityReference and @JsonIdentityInfo on the Person reference in Car as follows:
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERSON_ID")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "personId")
@JsonIdentityReference(alwaysAsId = true)
private Person person;
but when I POST the simplified JSON I am getting the following 404:
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: java.io.PushbackInputStream@25614608; line: 5, column: 1]Object id [2] (for myapp.ws.people.entity.Person) at [Source: java.io.PushbackInputStream@25614608; line: 2, column: 13].",
Upvotes: 0
Views: 1503
Reputation: 318
I think one way to achieve it is to
create a DTO class
class CarDto {
private long person;
private String typeOfCar;
}
then in your service have 2 repositories. one for person and other for car.
class PersonService {
public void post(CarDto car) {
Person person = personRepository.findByPersonId(car.getPerson());
Car newCar = new Car();
newCar.setPerson(person);
newCar.setTypeOfCar(car.getTypeOfCar);
carRepository.save(newCar);
}
}
Upvotes: 2