假设您有以下两个实体(为简洁起见,省略了大多数注释):
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
}
因此,基本上我们有一个Category
和Product
实体,它们具有延迟加载的单向关系。
据我了解,当您从数据库中获取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
进行查询时,在日志中看到生成的查询包括Product
和Category
之间的联接,完美。
现在,我想用相关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
扩展。
我只是想知道为什么这样做会如此。