Marian Klühspies
Marian Klühspies

Reputation: 17717

Hibernate self referencing ManyToMany join into single list with annotations

I´m facing a problem that is similar to Tinder´s matching logic, so I´m using that as an example.

enter image description here

My users can have a "match" between each other by having a common match entity with two user references.

@Data
@Entity
@Table(name = "match")
@EqualsAndHashCode(callSuper = true)
public class Match extends PanacheEntity {

    @Column(name = "matchDate")
    Calendar matchDate;

    @ManyToOne
    @JsonIgnore
    User userA;

    @ManyToOne
    @JsonIgnore
    User userB;

  }
}

I like to have a single reference to all matches the user is part of from both user entity objects, however I need to choose (assuming using "mappedBy") the other side of the relationship, being either the first or second user.

@Data
@Entity
@Table(name = "user_")
@EqualsAndHashCode(callSuper = true)
public class User extends PanacheEntity {

    @Column(name = "email")
    String email;

    @Column(name = "name")
    String name;

    // Needs to contain all "Matches", no matter if the user is referenced as "A" or "B"
    @OneToMany
    List<Match> matches;
}

I expect the List matches to be filled with objects the following query is representing, namely all matches that relate to the user, independent of the column.

select distinct match.id, user_a_id, user_b_id
from match,
     user_
where user_.id = match.user_a_id
   or user_.id = match.user_b_id

Something that gives me as a user any connection object I´m associated with, no matter if I´m the one who has invited or was invited.

Is there any way to implement it using Hibernate annotations?

Upvotes: 0

Views: 892

Answers (1)

SSK
SSK

Reputation: 3766

You can use @JoinColumn to specify the column name

Connection

@Data
@Entity
@Table(name = "connection")
@EqualsAndHashCode(callSuper = true)
public class Connection extends PanacheEntity {

    @ManyToOne
    @JsonIgnore
    @JoinColumn(name = "inviter_id")
    User inviter;

    @ManyToOne
    @JsonIgnore
    @JoinColumn(name = "invited_id")
    User invited;
}

User

@Data
@Entity
@Table(name = "user_")
@EqualsAndHashCode(callSuper = true)
public class User extends PanacheEntity {

    @Column(name = "email")
    String email;

    @Column(name = "name")
    String name;

    @OneToMany(mappedBy = "inviter")
    List<Connection> inviterConnections;
 
    @OneToMany(mappedBy = "invited")
    List<Connection> invitedConnections;
}

Update based on comments

you can try @JoinColumns on Connection as shown below, but it will give you and clause.

@JoinColumns(value = {
            @JoinColumn(name = "id", referencedColumnName = "inviter_id"),
            @JoinColumn(name = "id", referencedColumnName = "invited_id") })
User user;

Upvotes: 1

Related Questions