Предположим, у меня есть 2 сущности Parent
и Child
, где родитель содержит 1..n потомков:
@Entity
@Data @NoArgsConstructor
public class Parent {
@Id @GeneratedValue
private long id;
private String basic;
private String detail;
@OneToMany(fetch = FetchType.EAGER)
private Set<Child> children = new HashSet<>();
public Parent(String basic, String detail, Set<Child> children) {...}
}
@Entity
@Data @NoArgsConstructor
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private long id;
private String basic;
private String detail;
public Child(String basic, String detail) {...}
}
Я могу загрузить родительские объекты с помощью JpaRepository:
public interface ParentRepository extends JpaRepository<Parent, Long> { }
// in Controller or Service
List<Parent> parents = parentRepository.findAll();
Я пытаюсь использовать проекции. По этой причине я хочу знать, можно ли вручную загрузить родителей с помощью запроса, чтобы я мог загружать только необходимые данные. В идеальном мире это может выглядеть примерно так:
// Dtos, the String detail is not required for both Parent and Child
@Value
public class ParentDto {
long id;
String basic;
Collection<Child> children;
public ParentDto(long id, String basic, Collection<ChildDto> children) {...}
}
@Value
public class ChildDto {
long id;
String basic;
public ChildDto(long id, String basic) {...}
}
и
public interface ParentRepository extends JpaRepository<Parent, Long> {
// Projection - *NOT WORKING*, this is what i would like
@Query("select p.id, p.basic, p.children.id, p.children.basic from Parent p")
List<ParentDto> findAllProjected();
}
Это, очевидно, не удастся, потому что он объединит всех родителей со своим ребенком, что приведет к строкам amount_of_parents * amount_of_their_children. ParentDto потребовалось бы устройство сжатия public ParentDto(long id, String basic, ChildDto child) {...}
, поэтому у меня было n ParentDtos на одного родителя, где n - это число дочерних элементов, которые есть у родителя.
Нужно ли вручную группировать строки по идентификаторам родителей и собирать ChildDtos вместе? Могу ли я решить эту проблему с помощью подвыбора? Я знаю, что Jpa решает эту проблему, выбирая родителей и выполняя 1 выборку для каждого родителя, выбирая их детей (когда я использую метод автоматического создания репозитория). Я действительно надеялся, что проекции / представления будут намного проще, поскольку они являются таким фундаментальным требованием для меня и, скорее всего, для многих других приложений. Необходимость всегда загружать все данные, загружать только нужные данные, но без их ассоциаций или необходимость вручную загружать ассоциации для каждого объекта, выглядит как бампер.
Примечание: я попробовал InterfaceProjection, но не хочу его использовать, поскольку он загружает все данные и удаляет ненужные части только при сериализации в json.
Спасибо за привет!