5

I am trying to develop spring rest api with hibernate. after searching in google, I have not find solution to lazy loading. I have two entity like below:

University.java

@Entity()
@Table(schema = "core", name = "university")
public class University extends BaseEntity {

    private String uniName;
    private String uniTelephon;


    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "university", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<Student> students;

//setter and getter
}

Student.java

@Entity
@Table(schema = "core",name = "student")
public class Student {

    @Id
    @GeneratedValue            
    private long id;        

    private String firstName;        

    private String lastName;        

    private String section;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "UNIVERSITY_ID",nullable = false)
    @JsonBackReference
    private University university;
    // setter and getter
}

any my rest end point

@GetMapping("/list")
public ResponseEntity list() throws Exception {
    // I need to return just Universities But it return it eagerly with their students
    return new ResponseEntity(this.universityService.findAll(), HttpStatus.OK);
}

after calling the rest api, it return university with all students.

There is a way to tell Jackson to not serialize the unfetched objects or collections?

Can somebody help me with a proved solution?

1
  • 2
    Although the accepted answer is true, But the better answer is DO NOT return your entities to the client. First convert them to a Data Transfer Object (DTO) and send back those DTO objects to the client. Commented Nov 12, 2020 at 19:04

1 Answer 1

5

Try adding the following dependancy (depending on your hibernate version):

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-hibernate5</artifactId>
    <version>${jackson.version}</version>
</dependency>

And then (assuming you have a Java based configuration) add the following in the WebMvcConfigurerAdapter class:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(jackson2HttpMessageConverter());
}

@Bean
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(this.jacksonBuilder().build());

    return converter;
}

public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();

    Hibernate5Module hibernateModule = new Hibernate5Module();

    hibernateModule.configure(Feature.FORCE_LAZY_LOADING, false);

    builder.modules(hibernateModule);

    // Spring MVC default Objectmapper configuration
    builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    builder.featuresToDisable(MapperFeature.DEFAULT_VIEW_INCLUSION);

    return builder;
}

It should force the Jackson's objectMapper to not fetch lazy-loaded values.

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

4 Comments

its through the below exception HTTP Status 500 - Could not write content: failed to lazily initialize a collection of role: a2.asena.cashModel.University.students, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->a2.asena.cashModel.University["students"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: a2.asena.cashModel.University.students, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->a2.asena.cashModel.University["students"])
for above exception solution is overriding Filter in Appinitializer @Override protected Filter[] getServletFilters() { return new Filter[]{new HiddenHttpMethodFilter(), new MultipartFilter(), new OpenEntityManagerInViewFilter()}; is
some article says it is not proper solution
i can't say if it's a proper solution but i don't know others. I changed the answer to make it work with Spring MVC, the way the ObjectMapper was initialize before was wrong my bad.

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.