Фильтры гибернации для вложенных отношений ManyToMany - PullRequest
0 голосов
/ 29 января 2020

Я создаю Java приложение с Hibernate.

Я изо всех сил пытаюсь получить то, что хочу, без тысячи кодов котельной плиты.
У меня есть система управления пользователями.
A user может быть частью team (отношения @ManyToMany).
A team может быть частью debate (отношения @ManyToMany).
A debate может быть public.
A user может быть guest из debate (отношение @ManyToMany).
A debate имеет user, которому он принадлежит (отношение @ManyToOne).

Вот моя реализация

@Entity
@Table(name = "users")
public class User {

    @ManyToMany(mappedBy = "users")
    private Set<Team> teams = new HashSet<>();

    @ManyToMany(mappedBy = "guests")
    private Set<Debate> invitedDebates = new HashSet<>();

    @OneToMany(mappedBy = "owner")
    private Set<Debate> createdDebates = new HashSet<>();

    [...]
}
@Entity
@Table(name = "teams")
public class Team {

    @ManyToMany(mappedBy = "teams")
    private Set<Debate> debates = new HashSet<>();

    @JoinTable(name = "teams_users",
            joinColumns = {
                @JoinColumn(name = "team_id", referencedColumnName = "id")},
            inverseJoinColumns = {
                @JoinColumn(name = "user_id", referencedColumnName = "id")})
    @ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
    })
    private Set<User> users = new HashSet<>();

    [...]
}
@Entity
@Table(name = "debates")
public class Debate {

    @Column(name = "open_public")
    private boolean openPublic;

    @JoinColumn(name = "owner_id", referencedColumnName = "id", updatable = false)
    @ManyToOne(optional = false)
    private User owner;

    @JoinTable(name = "debates_teams",
            joinColumns = {
                @JoinColumn(name = "debate_id", referencedColumnName = "id")},
            inverseJoinColumns = {
                @JoinColumn(name = "team_id", referencedColumnName = "id")})
    @ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
    }, fetch = FetchType.EAGER)
    private Set<Team> teams = new HashSet<>();

    @JoinTable(name = "debates_guests",
            joinColumns = {
                @JoinColumn(name = "debate_id", referencedColumnName = "id")},
            inverseJoinColumns = {
                @JoinColumn(name = "user_id", referencedColumnName = "id")})
    @ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
    }, fetch = FetchType.EAGER)
    private Set<User> guests = new HashSet<>();

    [...]
}

То, что я хотел бы получить: с известным user, выбирающим все debate s, которые либо опубликованы c, либо созданный user, либо в котором есть team, к которому принадлежит user.

Пока я делаю этот запрос

    session.createQuery("SELECT d "
        + "FROM Debate d "
        + "LEFT JOIN d.teams t"
        + "LEFT JOIN User u "
        + " ON u = d.owner "
        + " OR u IN (d.guests) "
        + " OR u IN (t.users) "
        + "WHERE u = :user "
        + " OR d.options.openPublic = :isPublic", Debate.class)
        .setParameter("user", myUser)
        .setParameter("isPublic", true)
        .getResultList();

Во-первых ... это некрасиво.
Во-вторых, мое приложение, если оно намного больше (debate принадлежит document, которое относится к category, существует right управление user s, et c, et c ...), поэтому я должен повторно использовать этот образец кода в другой форме во многих разных местах.

Мне интересно, нельзя ли все это сделать с помощью Hibernates @ Filters.
Легко интегрировать для owner и openPublic, но я не могу установить фильтр типа user IN teams.users

Надеюсь, мои объяснения не слишком запутаны!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...