In my Spring boot application I have a query which should return a distinct List of Focus’ (works perfectly in MySQL)
@Query(value = "SELECT DISTINCT * FROM Focus F " +
"JOIN FrameworkFoci FF on FF.focusID = F.focusID " +
"JOIN FocusGroups FG on FF.frameworkID = FG.frameworkID " +
"JOIN GroupMembers GM on FG.groupID = GM.groupID " +
"JOIN Users U on GM.userID = U.userID " +
"WHERE U.userID = :userID", nativeQuery = true)
List<Focus> findByUserID(@Param("userID") Long userID);
However this does not return distinct values, duplicates are contained in the resulting list. Another issue is that I can’t return a whole entity using @Query annotation – changing my query to SELECT DISTINCT(F) FROM Focus F gives the error java.sql.SQLSyntaxErrorException: Unknown column 'F' in 'field list'.
Furthermore, I tried changing adjusting the query to the following
@Query(value = "SELECT DISTINCT * FROM FrameworkFoci FF " +
"JOIN FocusGroups FG on FF.frameworkID = FG.frameworkID " +
"JOIN GroupMembers GM on FG.groupID = GM.groupID " +
"JOIN Users U on GM.userID = U.userID " +
"WHERE U.userID = :userID", nativeQuery = true)
however this produced the error java.sql.SQLException: Column 'focusCategory' not found.
Why is the query not returning distinct values? And why can’t I return a whole entity nor use the second query?
Focus Entity:
@Entity
public class Focus {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long focusID;
@Column(name = "focusCategory")
private String focusCategory;
private String focusName;
private String focusExplanation;
@OneToMany(mappedBy = "focus")
private Set<Rating> ratings;
@ManyToMany
@JoinTable(name = "FrameworkFoci",
joinColumns = @JoinColumn(
name = "focusID"),
inverseJoinColumns = @JoinColumn(
name = "frameworkID"))
private Set<Framework> frameworks;
//image
protected Focus(){}
public Focus(String focusName, String focusCategory, String focusExplanation) {
this.focusCategory = focusCategory;
this.focusName = focusName;
this.focusExplanation = focusExplanation;
}
public Focus(String focusCategory, String focusName, String focusExplanation, Set<Rating> ratings){
this.focusCategory = focusCategory;
this.focusName = focusName;
this.focusExplanation = focusExplanation;
this.ratings = ratings;
}
public Long getFocusId() {
return focusID;
}
public void setFocusId(Long focusID) {
this.focusID = focusID;
}
public String getFocusCategory() {
return focusCategory;
}
public void setFocusCategory(String focusCategory) {
this.focusCategory = focusCategory;
}
EDIT:
I’ve switched from SQL to JPQL with the following query:
@Query(value = "SELECT DISTINCT focus FROM Focus focus " +
"WHERE focus.frameworks.groups.groupMembers.user.userID =:userID ")
I now get an error org.hibernate.QueryException: illegal attempt to dereference collection [focus0_.focusID.frameworks] with element property reference [groups]
Framework entity:
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "frameworkID")
public class Framework {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long frameworkID;
private String frameworkName;
@ManyToMany
@JoinTable(name = "FrameworkFoci",
joinColumns = @JoinColumn(
name = "frameworkID"),
inverseJoinColumns = @JoinColumn(
name = "focusID"))
private Set<Focus> frameworkFoci = new HashSet<>();
@OneToMany(mappedBy = "framework", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
private Set<Group> groups;
public Framework(){}
Advertisement
Answer
The following query solves the issue
@Query(value = "SELECT DISTINCT focus FROM Focus focus " +
"JOIN focus.frameworks frameworks " +
"JOIN frameworks.groups groups " +
"JOIN groups.groupMembers groupMembers "+
"WHERE groupMembers.userID =:userID ")
List<Focus> findByUserID(@Param("userID") Long userID);
Frameworks and GroupMembers are collections and hence needed to be joined, otherwise illegal attempt to dereference collection [focus0_.focusID.frameworks] with element property reference [groups] was produced