Допустим, у вас есть следующие две сущности (большинство аннотаций опущено для краткости):
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 и имею следующие проекции:
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
с идентификаторомсвязанные Category
.Поэтому я изменяю его на:
public interface ProductBasicProjection {
Long getId();
String getName();
@Value("#{target.category.id}")
Long getCategoryId();
}
Я полагаюсь на идентификатор, доступный в обработчике.Когда я запрашиваю базу данных, используя ProductBasicProjection
все в порядке.Однако, когда я теперь запрашиваю базу данных, используя ProductFullProjection
, я получу дополнительный вызов для извлечения соответствующего Category
.Обратите внимание, что ProductFullProjection
расширяет ProductBasicProjection
.
Очевидно, что я могу решить эту проблему, создав ProductBaseProjection
, который просто содержит поля Product
, а затем в ProductBasicProjection
используйте @Value("#{target.category.id}")
иоставьте ProductFullProjection
как есть, за исключением расширения от ProductBaseProjection
вместо ProductBasicProjection
.
Мне просто интересно, почему это ведет себя так, как оно.