Если у меня есть сущность, которая содержит @OneToMany
, с использованием JPA Как выбрать сущность и только подмножество связанных дочерних элементов? Я не могу использовать аннотации @Where
или @Filter
.
Подробнее Я перевожу нашу бизнес-модель во что-то более общее, поэтому не беспокойтесь о примере, не имеющем смысла в реале Но у Query есть много (больше, чем этот пример) случаев left join fetch
. Друг не имеет отношений и только строковое имя.
@Entity
public class Parent {
@Id
@GeneratedValue
private int parentId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "friendId")
private Friend friends;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", cascade = CascadeType.ALL)
private Set<Child> childrenSet = new HashSet<>();
}
@Entity
public class Child {
@Id
@GeneratedValue
private int childId;
private boolean blonde;
@ManyToOne(fetchType.LAZY, cascade = CascadeType.ALL)
private Parent parent;
}
@Query( "SELECT p " +
"FROM Parent p " +
"JOIN FETCH p.friends f " +
"LEFT JOIN FETCH p.childrenSet c " +
"WHERE f.name IS NOT NULL " +
"AND c.blonde = true")
List<Parent> getParentsWithListOfOnlyBlondeChildren();
Тестовый класс
@Transactional
@SpringBootTest
@RunWith(SpringRunner.class)
@DataJpaTest
public class TestParentRepo {
@PersistenceContxt
private EntityManager entityManager;
@Autowired
private ParentRepo parentRepo;
@Before
public void setup() {
Child c1 = new Child();
c1.setBlonde(true);
Child c2 = new Child();
c2.setBlonde(false);
Friend friend1 = new Friend();
friend1.setName("friend1");
Set<Child> children = new HashSet<>();
children.add(c1);
children.add(c2);
Parent parent1 = new Parent();
parent1.setFriends(friend1);
c1.setParent(parent1);
c2.setParent(parent1);
entityManager.persist(friend1);
entityManager.persist(parent1);
entityManager.persist(c1);
entityManager.persist(c2);
entityManager.flush();
entityManager.clear();
}
@Test
public void runTest() {
List<Parent> parent = parentRepo.getParentsWithListOfOnlyBlondeChildren();
System.out.println(parent);
}
}
Теперь при отладке I GET является родительским объектом с ОБА дочерними элементами в наборе. Что я ХОЧУ является родителем только с c1 (блондин = истина).
Каким должен быть запрос, чтобы отфильтровать связанные дочерние объекты, которые не соответствуют критериям?
Я стараюсь избегать выполнения: Query Parents, для каждого родителя Query Children, соответствующего критериям. Редактировать После дополнительного тестирования я обнаружил, что это не работает только при выполнении тестов, ie, проблема заключается в получении ожидаемого результата с использованием H2 DB в модульных тестах. Запрос работает нормально при работе с фактическим MySQL экземпляром.