我是Spring Data Rest的新手,并试图尝试其基本概念。到目前为止,一切工作都很好,但是几天前,我注意到将预测投入业务后,应用程序性能突然下降。

这些是我的实体,存储库和投影

@Entity
public class Item {

    @Id
    @GeneratedValue(strategy = TABLE)
    private long id;

    private String code;

    private String name;

    @ManyToOne(targetEntity=Category.class)
    @JoinColumn(name="category_id", referencedColumnName="id")
    private Category category;

    //getters & setters
}

@Entity
public class Category {

    @Id
    @GeneratedValue(strategy = TABLE)
    private long id;

    private String name;

    @OneToMany(mappedBy="category", targetEntity=Item.class, fetch=FetchType.LAZY)
    private Set<Item> items;

    //getters & setters
}

@RepositoryRestResource(excerptProjection=ItemExcerpt.class)
public interface ItemRepository extends CrudRepository<Item, Long>{

}

@RepositoryRestResource
public interface CategoryRepository extends CrudRepository<Category, Long>{

}

@Projection(name="excerpt", types=Item.class)
public interface ItemExcerpt {

    String getName();
}

因此,一切正常,直到我将摘录投影添加到ItemRepository @RepositoryRestResource(excerptProjection=ItemExcerpt.class)
在执行此操作之前,当我命中http://localhost:9191/categories时,Hibernate的输出是我所期望的:
select
        category0_.id as id1_0_,
        category0_.name as name2_0_
    from
        category category0_

这是添加excerptProjection=ItemExcerpt.class后得到的输出
Hibernate:
    select
        category0_.id as id1_0_,
        category0_.name as name2_0_
    from
        category category0_
Hibernate:
    select
        items0_.category_id as category4_1_0_,
        items0_.id as id1_1_0_,
        items0_.id as id1_1_1_,
        items0_.category_id as category4_1_1_,
        items0_.code as code2_1_1_,
        items0_.name as name3_1_1_
    from
        item items0_
    where
        items0_.category_id=?

我的结论是,摘录投影使@OneToMany关系上的懒惰获取被忽略,从而导致性能下降。
有谁知道绕过此问题的方法,或者这可能是预期的行为?

最佳答案

摘录预测并不是完全忽略了懒惰提取。更具体地,就是摘录投影告诉 Spring 数据无论将在何处返回收集资源都包括摘录数据。
从引用文档Projections Excerpts中,“摘录是自动应用于资源集合的投影。”不幸的是,spring-hateoas会忽略该属性,而是将超媒体链接放入资源中。我发现没有注释的组合可以在保留输出的同时为您纠正此行为。 @JsonIgnore不会阻止额外的查询。 @RestResource(exported = false)将阻止查询,但也将阻止超媒体链接。

10-06 05:13