Reputation: 5648
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
In the reference, they only mention how to do nested projection with JPQL.
Assume I have these projection:
public interface ThreadWithContent {
Integer getId();
String getTitle();
UserSummary getAuthor();
}
public interface UserSummary {
Integer getId();
}
How can I query the Thread with projection using native query, I tried this:
@Query(value =
"select thread.id as id,thread.title as title,author.id as authorId "+
"from thread inner join users as author " +
"on thread.author_id = author.id " +
"where thread.id = ?1",nativeQuery = true)
ThreadWithContent getThreadsById(Integer threadID);
But it looks like Spring Data can only map the thread
entity, but can't map the author
enitity
{
"title": "Recusandae nihil fugiat deserunt.",
"author": null,
"id": 5
}
I have tried author.id as authorId
, author.id as author_Id
but none of them works.
Upvotes: 7
Views: 2259
Reputation: 1029
I implemented this feature using constructor for nested projection. Take into account that to call constructor you need to use class name together with package name
@Value("#{new com.mycompany.projections.BadgeProjection(target.badgeId, target.badgeName, target.badgeDescription, target.badgeImageUrl)}")
Complete example
Parent Projection
import org.springframework.beans.factory.annotation.Value;
import java.time.LocalDate;
public interface ChallengeProjection {
Long getId();
String getName();
String getDescription();
String getImageUrl();
LocalDate getStartDate();
LocalDate getEndDate();
@Value("#{new com.mycompany.projections.BadgeProjection(target.badgeId, target.badgeName, target.badgeDescription, target.badgeImageUrl)}")
BadgeProjection getBadge();
}
Nested Projection
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
public class BadgeProjection {
private Long id;
private String name;
private String description;
private String getImageUrl;
}
Spring Repository
@Repository
public interface WorkoutGroupRepository extends JpaRepository<WorkoutGroup, Long> {
@Query(value = "select wg.id, wg.name, wg.description, wg.image_url as imageUrl, wg.start_date as startDate, wg.end_date as endDate," +
" b.id as badgeId, b.name as badgeName, b.description as badgeDescription, b.image_url as badgeImageUrl " +
" from workout_group wg left join badge b on b.id = wg.badge_id where wg.start_date between :weekStartDate and :weekEndDate"
, nativeQuery = true)
List<ChallengeProjection> getChallengeProjectionByWeek(@Param("weekStartDate") LocalDate weekStartDate, @Param("weekEndDate") LocalDate weekEndDate);
}
Example result
[ {
"description" : "Challenge description 1",
"name" : "Challenge name 1",
"id" : 1,
"imageUrl" : "myimage.jpeg",
"startDate" : "2020-12-15",
"endDate" : "2020-12-23",
"badge" : {
"id" : 1,
"name" : "Badge 1",
"description" : "Badge 1",
"getImageUrl" : "myimage.jpeg"
}
} ]
Upvotes: 6