There are two problems that I do not understand. First, the error message on the console. It does not give me the whole error message. Therefore I do not understand the issue at all :S The IDE is STS.
Second, why do I get this error, "JsonMapping failed to lazily initialize a..."
@Test
public void testUpdateCar() throws Exception {
Car car = carRepository.findById(new Long(1)).get();
car.setBrand("Mazda");
car.setModel("326");
String putJSON = objectMapper.writeValueAsString(car);
mockMVC.perform(MockMvcRequestBuilders.put(String.format("/api/cars/%d", car.getId())).contentType(MediaType.APPLICATION_JSON_UTF8).content(putJSON))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.content().contentType("application/hal+json;charset=UTF-8"));
}
Car:
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne
private User owner;
private String brand;
private String model;
private String color;
private String plate;
private String additionals;
Update 1: The error itself:
com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: me.eraytuncer.carpool.entity.User.carList, could not initialize proxy - no Session (through reference chain: me.eraytuncer.carpool.entity.Car["owner"]->me.eraytuncer.carpool.entity.User["carList"])
Update 2:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String phone;
private String email;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "owner")
private List<Car> carList;
Update 3:
@PutMapping("/cars/{id}")
ResponseEntity<?> replaceCar(@RequestBody Car newCar, @PathVariable Long id) {
if (repository.existsById(id)) {
newCar.setId(id);
Resource<Car> carResource = assembler.toResource(repository.save(newCar));
try {
return ResponseEntity
.created(new URI(carResource.getId().expand().getHref()))
.body(carResource);
} catch (URISyntaxException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
} else {
throw new CarNotFoundException(id);
}
}
Update 4:
Adding @JsonIgnore solved the issue somehow. Maybe it was a misleading issue caused by infinite recursion?
Looks like field
private List<Car> carList;
is resolved lazily (default fetch type in @OneToMany
), which means it is populated from DB only when getter for this field is called. In your case it is called by Jackson serializer outside scope of the Hibernate session and property cannot be populated. Changing fetch
type to EAGER in @OneToMany
on carList
property should help.
Also consider using DTO pattern, because returning entities from API is considered as bad practice.