Customizing the Result of JPA Queries with Aggregation Functions Module (#7977)
* Customizing the Result of JPA Queries with Aggregation Functions Module * *Code fix for the PR #7977 * *Inclusion of a method and tests for queries returning Object[] for PR #7977 * *Assertions update PR #7977 * *Adjust in the integration tests PR #7977
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package com.baeldung.aggregation.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class Comment {
|
||||
@Id
|
||||
private Integer id;
|
||||
private Integer year;
|
||||
private boolean approved;
|
||||
private String content;
|
||||
@ManyToOne
|
||||
private Post post;
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Comment(int id, int year, boolean approved, String content, Post post) {
|
||||
this.id = id;
|
||||
this.year = year;
|
||||
this.approved = approved;
|
||||
this.content = content;
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(Integer year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public boolean isApproved() {
|
||||
return approved;
|
||||
}
|
||||
|
||||
public void setApproved(boolean approved) {
|
||||
this.approved = approved;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Post getPost() {
|
||||
return post;
|
||||
}
|
||||
|
||||
public void setPost(Post post) {
|
||||
this.post = post;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Comment)) {
|
||||
return false;
|
||||
}
|
||||
Comment comment = (Comment) o;
|
||||
return getId().equals(comment.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.baeldung.aggregation.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class Post {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String title;
|
||||
private String content;
|
||||
@OneToMany(mappedBy = "post")
|
||||
private List<Comment> comments;
|
||||
|
||||
public Post() {
|
||||
}
|
||||
|
||||
public Post(Integer id, String title, String content) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Post)) {
|
||||
return false;
|
||||
}
|
||||
Post post = (Post) o;
|
||||
return getId().equals(post.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.aggregation.model.custom;
|
||||
|
||||
public class CommentCount {
|
||||
private Integer year;
|
||||
private Long total;
|
||||
|
||||
public CommentCount(Integer year, Long total) {
|
||||
this.year = year;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Integer getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(Integer year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public Long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Long total) {
|
||||
this.total = total;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.aggregation.model.custom;
|
||||
|
||||
public interface ICommentCount {
|
||||
|
||||
Integer getYearComment();
|
||||
|
||||
Long getTotalComment();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.aggregation.repository;
|
||||
|
||||
import com.baeldung.aggregation.model.Comment;
|
||||
import com.baeldung.aggregation.model.custom.CommentCount;
|
||||
import com.baeldung.aggregation.model.custom.ICommentCount;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface CommentRepository extends JpaRepository<Comment, Integer> {
|
||||
|
||||
@Query("SELECT c.year, COUNT(c.year) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||
List<Object[]> countTotalCommentsByYear();
|
||||
|
||||
@Query("SELECT new com.baeldung.aggregation.model.custom.CommentCount(c.year, COUNT(c.year)) FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||
List<CommentCount> countTotalCommentsByYearClass();
|
||||
|
||||
@Query("SELECT c.year AS yearComment, COUNT(c.year) AS totalComment FROM Comment AS c GROUP BY c.year ORDER BY c.year DESC")
|
||||
List<ICommentCount> countTotalCommentsByYearInterface();
|
||||
|
||||
@Query(value = "SELECT c.year AS yearComment, COUNT(c.*) AS totalComment FROM comment AS c GROUP BY c.year ORDER BY c.year DESC", nativeQuery = true)
|
||||
List<ICommentCount> countTotalCommentsByYearNative();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.baeldung.aggregation;
|
||||
|
||||
import com.baeldung.aggregation.model.custom.CommentCount;
|
||||
import com.baeldung.aggregation.model.custom.ICommentCount;
|
||||
import com.baeldung.aggregation.repository.CommentRepository;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
|
||||
@Sql(scripts = "/test-aggregation-data.sql")
|
||||
public class SpringDataAggregateIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CommentRepository commentRepository;
|
||||
|
||||
@Test
|
||||
public void whenQueryWithAggregation_thenReturnResult() {
|
||||
List<Object[]> commentCountsByYear = commentRepository.countTotalCommentsByYear();
|
||||
|
||||
Object[] countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019[0], is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019[1], is(1l));
|
||||
|
||||
Object[] countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018[0], is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018[1], is(2l));
|
||||
|
||||
Object[] countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017[0], is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017[1], is(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenQueryWithAggregation_thenReturnCustomResult() {
|
||||
List<CommentCount> commentCountsByYear = commentRepository.countTotalCommentsByYearClass();
|
||||
|
||||
CommentCount countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019.getYear(), is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019.getTotal(), is(1l));
|
||||
|
||||
CommentCount countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018.getYear(), is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018.getTotal(), is(2l));
|
||||
|
||||
CommentCount countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017.getYear(), is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017.getTotal(), is(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenQueryWithAggregation_thenReturnInterfaceResult() {
|
||||
List<ICommentCount> commentCountsByYear = commentRepository.countTotalCommentsByYearInterface();
|
||||
|
||||
ICommentCount countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019.getYearComment(), is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019.getTotalComment(), is(1l));
|
||||
|
||||
ICommentCount countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018.getYearComment(), is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018.getTotalComment(), is(2l));
|
||||
|
||||
ICommentCount countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017.getYearComment(), is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017.getTotalComment(), is(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNativeQueryWithAggregation_thenReturnInterfaceResult() {
|
||||
List<ICommentCount> commentCountsByYear = commentRepository.countTotalCommentsByYearNative();
|
||||
|
||||
ICommentCount countYear2019 = commentCountsByYear.get(0);
|
||||
|
||||
assertThat(countYear2019.getYearComment(), is(Integer.valueOf(2019)));
|
||||
assertThat(countYear2019.getTotalComment(), is(1l));
|
||||
|
||||
ICommentCount countYear2018 = commentCountsByYear.get(1);
|
||||
|
||||
assertThat(countYear2018.getYearComment(), is(Integer.valueOf(2018)));
|
||||
assertThat(countYear2018.getTotalComment(), is(2l));
|
||||
|
||||
ICommentCount countYear2017 = commentCountsByYear.get(2);
|
||||
|
||||
assertThat(countYear2017.getYearComment(), is(Integer.valueOf(2017)));
|
||||
assertThat(countYear2017.getTotalComment(), is(1l));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
INSERT INTO post (id, title, content) VALUES (1, 'Comment 1', 'Content 1');
|
||||
INSERT INTO post (id, title, content) VALUES (2, 'Comment 2', 'Content 2');
|
||||
INSERT INTO post (id, title, content) VALUES (3, 'Comment 3', 'Content 3');
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (1, 2019, false, 'Comment 1', 1);
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (2, 2018, true, 'Comment 2', 1);
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (3, 2018, true, 'Comment 3', 2);
|
||||
INSERT INTO comment (id, year, approved, content, post_id) VALUES (4, 2017, false, 'Comment 4', 3);
|
||||
Reference in New Issue
Block a user