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?