Filtrowanie po obiektach znajdujących się w tabeli z relacją OneToMany

0

Cześć,

mam problem z filtrowaniem tabeli po propertkach znadujących się w tabeli, z która jest w relacji OneToMany, podglądowo

class A {

@OneToMany(fetch.. mappedBy)
private List<B> b;

}
class B {
private String property1;
private String property2;
}

Używając specyfikacji robię joina, dodaje Predicate który mówi, że chcemy pobrać tylko te które mają property1 = "ABC", (root.join(B).get(property1).equals("ABC")). W takim przypadku pobierze mi wszystkie obiekty klasy A, które mają chociaż jeden rekord B spełniający podane kryteria. Mój problem jest taki, że chciałbym by również Obiekty klasy B zostały przefiltrowane po podanych kryteriach jeśli kryteria dotyczą klasy B, jak to ugryźć? W tej chwili tworzą mi się dwa query, jedno by ściągnąć wszystkie A które spełniają podane kryteria, drugie query by ściągnąć wszystkie B, które są w relacji do znalezionych A. Bardzo prosiłbym o wskazanie jaką drogę wybrać by rozwiązać to wyzwanie :)

1

@Patryk Brzuchacz:

Bosch ....aleś się postarał.

  1. te klasy są zupełnie nie przygotowane do pracy z bazą danych, m.in z braku kluczy. Być może masz to w oryginale, ale nikt nie będzie sie tym zajmował.
  2. nie wiem o której funkcjonalnosci predykatu mowa, czy przerzucony na bazę danych, czy filtrujesz na kliencie

Wróć z prawidziwym kodem, a nie ogryzkami.

2

@OneToMany to zawsze źródło wielu problemów i zero zalet xd

Jak zrobić lepiej:

class A {

  Long id;

}
class B {
private Long id;
private String property1;
private String property2;
private Long aId;
}

potem masz sobie Springowe CRUDowe

public interface ARepository extends CrudRepository<A, Long> {}

oraz

public interface BRepository extends CrudRepository<B, Long> {

  Set<B> findAllByProperty1(String property1);
  Set<B> findAllByProperty2(String property2);
}

i sobie robisz różne filtrowania na poziomie klasy B i jej propertiesów. Jak już znajdziesz przefiltrowane rekordy (na poziomie javy, nie sqla), to pogrupuj sobie idki do parenta czyli do klasy A i wywołasz

aRepository.findAllByIds(aIds)

gdzie aIds to nie groźny AIDS, ale zgrupowane idki z przefiltrowanych obiektów B (żeby nie robić przy okazji N+1 problemu)

i viola :) kod na tacy praktycznie

1 użytkowników online, w tym zalogowanych: 0, gości: 1