2

Spring Boot REST service backed by MySQL 5.6 here. I have the following tables:

DESCRIBE profiles;
+----------------------------+---------------------+------+-----+---------+----------------+
| Field                      | Type                | Null | Key | Default | Extra          |
+----------------------------+---------------------+------+-----+---------+----------------+
| profile_id                 | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| profile_given_name         | varchar(100)        | YES  | MUL | NULL    |                |
| profile_surname            | varchar(100)        | YES  | MUL | NULL    |                |
+----------------------------+---------------------+------+-----+---------+----------------+

describe friendships;
+----------------------+---------------------+------+-----+---------+----------------+
| Field                | Type                | Null | Key | Default | Extra          |
+----------------------+---------------------+------+-----+---------+----------------+
| friendship_id        | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| requester_profile_id | bigint(20) unsigned | NO   | MUL | NULL    |                |
| recipient_profile_id | bigint(20) unsigned | NO   | MUL | NULL    |                |
+----------------------+---------------------+------+-----+---------+----------------+

The profiles table represents users of a system, and friendships represents a many-to-many relationship of which users are friends with which other users. When a user/profile sends a "Friend Request" to a user, they are considered to be therequester in of the friendship. Conversely, those who receive Friend Requests from others are the recipients.

These tables correspond to the following JPA entities:

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

@Entity
@Table(name = "profiles")
@AttributeOverrides({
        @AttributeOverride(name = "id", column=@Column(name="profile_id"))
})
@JsonDeserialize(using = ProfileDeserializer)
public class Profile extends BaseEntity implements Comparable<Profile> {
    @Column(name = "profile_given_name")
    private String givenName;

    @Column(name = "profile_surname")
    String private surname;
}

@Entity
@Table(name = "friendships")
@AttributeOverrides({
        @AttributeOverride(name = "id", column=@Column(name="friendship_id"))
})
public class Friendship extends BaseEntity {
    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = "requester_profile_id", referencedColumnName = "profile_id")
    @NotNull
    private Profile requester;

    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = "recipient_profile_id", referencedColumnName = "profile_id")
    @NotNull
    private Profile recipient;
}

In the MySQL command-line client I can figure out who a particular Profile is friends with given the following query:

SELECT      f.recipient_profile_id as profile_friends
FROM        profiles p
INNER JOIN  friendships f
ON f.requester_profile_id = p.profile_id
WHERE       p.profile_id = 1

UNION

SELECT      f.requester_profile_id
FROM        profiles p
INNER JOIN  friendships f
ON  f.recipient_profile_id = p.profile_id
WHERE       p.profile_id = 1;

This produces output like:

+-----------------+
| profile_friends |
+-----------------+
|               2 |
|               3 |
|               4 |
+-----------------+

Above, we see that profile_id = 1 is friends with 3 other profiles, profile_id IN {2,3,4}.

I'm trying to write the equivalent JPQL query in my CrudRepository and a having difficulty:

public interface FriendshipRepository implements CrudRepository<Friendship,Long> {
    @Query(" ??? ")
    public Set<Profile> getFriendsByProfile(@Param("profile") Profile profile);
}

Any ideas as to how I could write the @Query(...) to run the equivalent SELECT statement up above?

smeeb
  • 27,777
  • 57
  • 250
  • 447
  • Possible duplicate of [UNION to JPA Query](https://stackoverflow.com/questions/18958614/union-to-jpa-query) – Jens Schauder Feb 01 '18 at 10:08
  • You could use that SQL query simply add native=true to the Query annotation and take care to provide all necessary fields to construct a Profile. – Simon Martinelli Feb 01 '18 at 11:35

0 Answers0