在Spring Data Jpa投影中包含相关实体标识符,而无需额外调用数据库

时间:2018-08-26 19:44:53

标签: spring-data-jpa

假设您有以下两个实体(为简洁起见,省略了大多数注释):

public class Category {
    private Long id;
    private String name;

    // constructor, getters, equals/hashcode
}

public class Product {
    private Long id;
    private String name;

    @ManyToOne(fetch = FetchMode.LAZY)
    @JoinColumn(value = "category_id")
    private Category category;

    // constructor, getters, equals/hashcode
}

因此,基本上我们有一个CategoryProduct实体,它们具有延迟加载的单向关系。

据我了解,当您从数据库中获取Product实体时,无需获取数据库即可调用product.getCategory().getId(),因为相关实体的标识符已获取并在处理程序中可用。

这可以在我的应用程序中正常工作。

我正在使用Spring Data Projections,并且具有以下预测:

public interface CategoryBasicProjection {
    Long getId();
    String getName();
}

public interface ProductBasicProjection {
    Long getId();
    String getName();
}

public interface ProductFullProjection extends ProductBasicProjection {

    CategoryBasicProjection getCategory();
}

这非常好用,当我使用ProductBasicProjection查询存储库时,便获得了原始属性。当我使用ProductFullProjection进行查询时,在日志中看到生成的查询包括ProductCategory之间的联接,完美。

现在,我想用相关ProductBasicProjection的ID充实Category。所以我将其更改为:

public interface ProductBasicProjection {
    Long getId();
    String getName();

    @Value("#{target.category.id}")
    Long getCategoryId();
}

我依靠处理程序中可用的ID。当我使用ProductBasicProjection查询数据库时,一切都很好。但是,当我现在使用ProductFullProjection查询数据库时,将获得一个额外的调用来获取相关的Category。请注意,ProductFullProjection扩展了ProductBasicProjection

很明显,我可以通过创建一个ProductBaseProjection来解决此问题,该{}仅仅包含Product的字段,然后在ProductBasicProjection中使用@Value("#{target.category.id}")并保留{{1 }}不变,只是从ProductFullProjection而不是ProductBaseProjection扩展。

我只是想知道为什么这样做会如此。

0 个答案:

没有答案