Я использую Spring Data JPA, и у меня есть объекты, которые отображаются в соответствующие таблицы.Мне нужно запросить результаты, чтобы я мог выбрать всех родителей и одного ребенка на каждого родителя на основе их strength
.
@Entity
public class Parent {
@Id
Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> children;
}
@Entity
public class Child {
@Id
Long id;
@Enumerated(EnumType.STRING)
private Strength strength;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "parent_id", nullable = false, insertable = true, updatable = false)
private Parent parent;
}
public Enum Strength {
STRONG,
NORMAL,
WEAK
}
У меня есть базовый репозиторий crud:
@Repository
public interface ParentRepository extends CrudRepository<Parent, Long>{}
Некоторые правила и предположения:
- Ребенок принадлежит одному родителю
- У родителя может быть много дочерних объектов в БД
- У родителя может быть 0 или 1 дочерний элемент, имеющий силу = STRONG
- У родителя будет 1 дочерний элемент, который имеет силу = NORMAL
- У родителя будет 0 или более дочерних объектов, имеющих силу = WEAK
- Слабый дочерний элемент никогда не возвращается
- Приведенный ниже метод
getParentAndStrongChildren
должен возвращать максимум 1 дочерний объект.
Я могу сделать запрос findAll
для метода родительского репозитория в Spring и затем отобразить результаты в памяти примерно так:
public List<Parent> getParentAndStrongChildren(){
List<Parent> parents = parentRepository
.findAll().stream()
.map(p -> {
if(p.getChildren() != null && p.getChildren.size() > 1){
Child found = p.getChildren().stream()
.filter(c -> c.getStrength() == Strength.STRONG)
.findFirst()
.orElseGet(()-> p.getChildren().stream()
.filter(c -> c.getStrength() == Strength.NORMAL)
.findFirst()
.orElse(null));
p.setChildren(found == null ? null : new Arrays.asList(found));
}
}
return parents;
}
Q: Есть лилюбой способ не делать фильтры в памяти и полагаться на JPQL и аннотацию @Query для достижения этой цели?