取得&在Spring Data REST中更新延迟加载的多个字段

时间:2016-06-17 18:04:58

标签: java spring spring-data-jpa openjpa spring-data-rest

如何正确公开延迟加载多个字段,以便用户GET / PATCH / POST / DELETE Spring Data REST中的许多实体关系?

例如,给定Student实体和Teacher实体受多对多关系约束,使用以下POJO:

@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...
}

为实体提供存储库:

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

// similar repository for student

当我发送GET给localhost:8080 /老师时,我得到:

"_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...)
    ]
}
...

但是,当我尝试GEThttp://localhost:8080/teacher/1/students时,我得到 404 Not Found ,即使老师&#34; Bill Billie&#34; 让学生在数据库中与他相关联。

有趣的是,如果我将FetchType更改为FetchType.EAGER,一切正常,我可以执行预期的GETPATCH等。 是什么赋予了?这可能是一个错误,还是我搞砸了什么?

tl; dr许多关系没有通过延迟抓取正确公开,但可以通过急切提取工作。我怎样才能懒惰地使用它?

编辑:如果重要,我使用Spring 4.2.6和Spring Boot 1.3.5,OpenJPA 2.4.1作为我的JPA提供者。

3 个答案:

答案 0 :(得分:1)

嗯我不确定为什么它不会自动提取更有经验的人会问这个问题,但是您可以为每个查询指定使用HQL连接提取的手动提取。

select x from X left join fetch x.y y

完成此工作后,您可以使用专门创建的控制器覆盖您的get语句,如下所述:Spring Data REST: Override repository method on the controller

我认为可能值得尝试的其他选项是在Spring数据存储库中添加@Lazy注释。

答案 1 :(得分:1)

尝试制作RestResources事务。

使用@Transactional

进行批注

答案 2 :(得分:0)

添加以下依赖项

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

添加配置类。

@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);
    }
}