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:
Fred
2019-10-29 21:34:29 -03:00
committed by ashleyfrieze
parent 18c6a1a0ab
commit 5914a5195a
7 changed files with 336 additions and 0 deletions

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,8 @@
package com.baeldung.aggregation.model.custom;
public interface ICommentCount {
Integer getYearComment();
Long getTotalComment();
}

View File

@@ -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();
}

View File

@@ -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));
}
}

View File

@@ -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);