Hibernate OneToMany zliczanie pogrupowanych wyników

Hibernate OneToMany zliczanie pogrupowanych wyników
MA
  • Rejestracja:prawie 4 lata
  • Ostatnio:3 miesiące
  • Postów:30
0

Hej,
mam prosta strukturę:

Kopiuj
@Entity
@Data
public class Comment {
  private Long id;
  private String comment;

  @OneToMany
  private List<CommentReaction> commentReactions;

  //Jak ogarnac taka liste, czytaj dalej
  List<ReactionCount> reactionsCount;
}
Kopiuj
@Entity
@Data
public class CommentReaction {
   private Long id;
   private User user;

   @Enumerated
   private Reaction reaction;
}
Kopiuj
public enum Reaction {
  OK, BAD;
}

Czy da się w obiekcie Comment w jakis posob np przy pomocy Formula czy czegos podobnego policzyc ile jest reakcji każdego typu np. do jakiegos obiektu typu

Kopiuj
@Data
public class ReactionCount {
   private Reaction reaction;
   private int reactionCount;
}
hzmzp
  • Rejestracja:ponad 11 lat
  • Ostatnio:42 minuty
  • Postów:630
0

Tak jak napisałeś, ogarniasz to sobie formułą, np po typie reakcji.

Kopiuj
public class Reaction {
 TypeEnum type;
 Comment comment;
}
public class Comment {
    @Formula("(SELECT COUNT(R.id) FROM Reaction R WHERE R.comment = id AND R.type = 'POSITIVE')")
    long positiveReactionCount;
}

MA
@hzmzp: czyli nie ma innej opcji bardziej wydajnej? bo aby obliczyc ile jest rezultatow kazdego typu musialbym robic osobne zapytania SQL? Z drugiej strony da sie jakos pracowac juz na pobranej raz liscie Reakcji. Bo przeciez List<CommentReaction> jest takim propertiesem w obiekcie Commemnt
CosherJeepersCreepers
obrzydliwe, a pozniej utrzymywanie tego sqla, a co bedzie jak zapomne w tym stringu zmienić a zmienie nazwe propa.. zgroza, nie po to są mappingi i F2 żeby musieć panietac o customowych sqlach. Nie wszystko musi miec testy, a w takim devowaniu już chyba tak...
hzmzp
  • Rejestracja:ponad 11 lat
  • Ostatnio:42 minuty
  • Postów:630
0

Możesz zrobić w sql trigger na dodawanie reakcji które aktualizuje (daje +1 do pola) positiveReactionCount

RequiredNickname
  • Rejestracja:prawie 5 lat
  • Ostatnio:około 5 godzin
  • Postów:620
1

Klasyczny przykład fiksowania problemów które programista sam sobie stworzył (używając JPA) ;)

Napisz sobie JPQL (lub native query) coś w stylu:

Kopiuj
@Query("SELECT new com.example.ReactionCount(cr.reaction, COUNT(cr)) " +
       "FROM CommentReaction cr WHERE cr.comment.id = :commentId " +
       "GROUP BY cr.reaction ORDER BY cr.reaction")
List<ReactionCount> countReactionsForComment(@Param("commentId") Long commentId);

I przerzuć obowiązek agregacji i zliczania na bazę danych.

Co do tych formuł hibernetowych to. nie używałem nigdy ale nie podoba mi się to ;)
W encji wolałbym trzymać dane a to jak gadam z db wolałbym zostawić na poziomie repozytoriów.

edytowany 2x, ostatnio: RequiredNickname
ZI
jedyna sluszna droga +1
DA
Możnaby rozważyć cache’owanie tego gdzieś, żeby nie uderzać cały czas do bazy, albo zrobić widok zmaterializowany. Typowo w wielu platformach - te dane nie muszą być aktualne z danego momentu. Taki youtube nie pokazuje liczby reakcji „na żywo”.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.