0

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?

Marian Klühspies
  • 15,824
  • 16
  • 93
  • 136

1 Answers1

1

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;
SSK
  • 3,444
  • 6
  • 32
  • 59
  • sadly it´s not working as expected. It still requires the "mappedBy" attribute on the other side pointing to one of both User variables, otherwise the results are empty. Have you any idea how it can be mapped to both? – Marian Klühspies Aug 13 '20 at 20:50
  • I have added mapped by and updated answer, please test the same. – SSK Aug 14 '20 at 03:06
  • But now we have two lists for each user which I want to prevent, I want to have a single one with all common connections without differentiating between invited and inviter. Another example would be Tinder matches, I'm interested in the match and both participants, not who invited whom. Maybe I should have taken that example from the beginning to make it more clear, sry – Marian Klühspies Aug 14 '20 at 04:47
  • You don't need to add mapped by. You can fetch data from connection table using connection repository. If you share your service class code that will be helpful. – SSK Aug 14 '20 at 06:14
  • @SKK I have no service class yet, I just wanted to let hibernate find the referenced connection objects by calling User.findById(). My intention was not to do it with additional work within a service but to cover it entirely over hibernate annotations if possible. I think otherwise I could also just use the SQL query I've posted in my question instead :) – Marian Klühspies Aug 14 '20 at 12:32
  • I have added `@JoinColumns` above. here it will join on two columns – SSK Aug 14 '20 at 14:57
  • thank you, I think that's not my point. The solution I'm looking at is something where the User object only holds one single List containing all connections he is a part of, no matter if he is the invited or inviter. In your solution you have a separation between inviter connections and invited connections. – Marian Klühspies Aug 14 '20 at 15:15
  • I´ve changed the example to make it a bit clearer. Now your user object would contain List userAMatches and List userBMatches which is odd, instead a List matches is what we would be interested in that includes everything – Marian Klühspies Aug 15 '20 at 08:17