Getting and updating lazy loaded many many fields in Spring Data REST

How do I set lazy-loaded many, many fields correctly so that users can get many entity relations in Spring Data REST GET / PATCH / POST / DELETE ?

For example, for a Student object and a Teacher object associated with a many-many relationship, with the following POJOs:

 @Entity public class Teacher { // owner of bidirectional relationship @Id private int id; private String name; @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "teacher_student", joinColumns = @JoinColumn(name = "teacher_id"), inverseJoinColumns = @JoinColumn(name = "student_id")) private Set<Student> students; // Constructor, getters/setters... } @Entity public class Student { @Id private int id; private String name; @ManyToMany(mappedBy = "students", fetch = FetchType.LAZY) private Set<Teacher> teachers; // Constructor, getters/setters... } 

Repositories are provided to objects:

 @RepositoryRestResource(path = "teacher") public interface TeacherRepository extends CrudRepository<Teacher, int> {} // similar repository for student 

When I send a GET to localhost: 8080 / teacher, I get:

 "_embedded": { "teacher": [ { "name": "Bill Billie", "_links": { "self": { "href": "http://localhost:8080/teacher/1" }, "teacher": { ... }, "students": { "href": "http://localhost:8080/teacher/1/students" } }}, (more teachers here...) ] } ... 

BUT , when I try to use GET for http: // localhost: 8080 / teacher / 1 / students , I get 404 Not found , although the Bill Billy teacher has a student associated with him in the database.

Interestingly, if I change FetchType to FetchType.EAGER , everything will be fine, and I will be able to execute the expected GET , PATCH , etc. What gives? Perhaps this is a mistake, or am I screwing something?

tl; dr Many, many relationships do not display correctly with a lazy set, but work great with impatience. How can I get a lazy choice to work with it?

Change If that matters, I am using Spring 4.2.6 with Spring Boot 1.3.5 and OpenJPA 2.4.1 as my JPA provider.

+6
source share
3 answers

Hmm, I don’t know why it will not be an automatic selection that someone more experienced would have to set, but you can specify manual selection using the HQL selection for each query.

 select x from X left join fetch xy y 

After completing this work, you can override the get statement using a specially created controller, as described here: Spring Data REST: override the repository method on the controller

Only another option that I think is worth a try adds the @Lazy annotation to your Spring repository.

+1
source

Try to make the RestResources transaction a transaction.

Annotate with @Transactional

+1
source

Add the following dependency

 <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate4</artifactId> </dependency> 

Add configuration class.

 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter{ public MappingJackson2HttpMessageConverter jacksonMessageConverter(){ MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); //Registering Hibernate4Module to support lazy objects mapper.registerModule(new Hibernate4Module()); messageConverter.setObjectMapper(mapper); return messageConverter; } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { //Here we add our custom-configured HttpMessageConverter converters.add(jacksonMessageConverter()); super.configureMessageConverters(converters); } } 
0
source

All Articles