0

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.

enter image description here

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?

4
  • show User entity and also your Controller method Commented Aug 9, 2019 at 12:51
  • The error line is at "String putJSON = objectMapper.writeValueAsString(car);" Commented Aug 9, 2019 at 12:55
  • Possible duplicate of Could not initialize proxy - no Session Commented Aug 9, 2019 at 13:15
  • Adding @JsonIgnore to private List<Car> carList; solved my problem. Maybe it was a misleading issue caused by nested json data? Commented Aug 9, 2019 at 13:17

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Did not help. Could you please check my Update 4?
Update 4 seems to confirm my explanation: @JsonIgnore makes Jackson ignore this field thus getter is not called and car list is not fetched from DB. Depends what you want - do you want this field to be return from your API? Also @Maciej Kowalski answer is valid - you should use @ManyToOne in Car entity, but this is not the source of your problem.
I would not need @JsonIgnore, If I used DTO pattern already. I see now ;)
0

You have mapped @OneToOne against @OneToMany. It should be @ManyToOne on the owning side:

    @ManyToOne
    @JoinColumn(name = "user_id") // if needed
    private User owner;

1 Comment

Upload the Controller logic
0

I faced the same issue and it got resolved by using @Transactional on the method. @Transactional help to keep open the session so that lazy collection could be fetched.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.