BAEL-6163 - Add code examples for the article "Querydsl vs. JPA Criteria"
This commit is contained in:
parent
8760727aa0
commit
bd5512454d
@ -15,6 +15,18 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- Spring Data -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- QueryDSL -->
|
<!-- QueryDSL -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.querydsl</groupId>
|
<groupId>com.querydsl</groupId>
|
||||||
@ -36,6 +48,16 @@
|
|||||||
<version>${hibernate-core.version}</version>
|
<version>${hibernate-core.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||||
|
<version>${hibernate-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bsc.maven</groupId>
|
||||||
|
<artifactId>maven-processor-plugin</artifactId>
|
||||||
|
<version>5.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-dbcp</groupId>
|
<groupId>commons-dbcp</groupId>
|
||||||
<artifactId>commons-dbcp</artifactId>
|
<artifactId>commons-dbcp</artifactId>
|
||||||
@ -103,24 +125,36 @@
|
|||||||
<version>${maven-compiler-plugin.version}</version>
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgument>-proc:none</compilerArgument>
|
<compilerArgument>-proc:none</compilerArgument>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- QueryDSL plugin -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mysema.maven</groupId>
|
<groupId>org.bsc.maven</groupId>
|
||||||
<artifactId>apt-maven-plugin</artifactId>
|
<artifactId>maven-processor-plugin</artifactId>
|
||||||
<version>${apt-maven-plugin.version}</version>
|
<version>5.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
<id>process</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>process</goal>
|
<goal>process</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
<configuration>
|
<configuration>
|
||||||
<outputDirectory>target/generated-sources/java</outputDirectory>
|
<processors>
|
||||||
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
|
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
|
||||||
|
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
|
||||||
|
</processors>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-jpamodelgen</artifactId>
|
||||||
|
<version>${hibernate-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
@ -132,6 +166,7 @@
|
|||||||
<commons-dbcp.version>1.4</commons-dbcp.version>
|
<commons-dbcp.version>1.4</commons-dbcp.version>
|
||||||
<apt-maven-plugin.version>1.1.3</apt-maven-plugin.version>
|
<apt-maven-plugin.version>1.1.3</apt-maven-plugin.version>
|
||||||
<hibernate-core.version>6.4.2.Final</hibernate-core.version>
|
<hibernate-core.version>6.4.2.Final</hibernate-core.version>
|
||||||
|
<spring-boot.version>3.2.3</spring-boot.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria.entities;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToMany;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class GroupUser {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String login;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "groupUsers", cascade = CascadeType.PERSIST)
|
||||||
|
private Set<UserGroup> userGroups = new HashSet<>();
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "groupUser")
|
||||||
|
private Set<Task> tasks = new HashSet<>(0);
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
return login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogin(String login) {
|
||||||
|
this.login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<UserGroup> getUserGroups() {
|
||||||
|
return userGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserGroups(Set<UserGroup> userGroups) {
|
||||||
|
this.userGroups = userGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Task> getTasks() {
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTasks(Set<Task> tasks) {
|
||||||
|
this.tasks = tasks;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria.entities;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Task {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private GroupUser groupUser;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupUser getUser() {
|
||||||
|
return groupUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(GroupUser groupUser) {
|
||||||
|
this.groupUser = groupUser;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria.entities;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToMany;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class UserGroup {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToMany(cascade = CascadeType.PERSIST)
|
||||||
|
private Set<GroupUser> groupUsers = new HashSet<>();
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<GroupUser> getGroupUsers() {
|
||||||
|
return groupUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupUsers(Set<GroupUser> groupUsers) {
|
||||||
|
this.groupUsers = groupUsers;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria.repositories;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.UserGroup;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.UserGroup_;
|
||||||
|
|
||||||
|
public interface UserGroupJpaSpecificationRepository extends JpaRepository<UserGroup, Long>,
|
||||||
|
JpaSpecificationExecutor<UserGroup> {
|
||||||
|
|
||||||
|
default List<UserGroup> findAllWithNameInAnyList(List<String> names1, List<String> names2) {
|
||||||
|
return findAll(specNameInAnyList(names1, names2));
|
||||||
|
}
|
||||||
|
|
||||||
|
default Specification<UserGroup> specNameInAnyList(List<String> names1, List<String> names2) {
|
||||||
|
return (root, q, cb) -> cb.or(
|
||||||
|
root.get(UserGroup_.name).in(names1),
|
||||||
|
root.get(UserGroup_.name).in(names2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria.repositories;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||||
|
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.QUserGroup;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.UserGroup;
|
||||||
|
import com.querydsl.core.BooleanBuilder;
|
||||||
|
import com.querydsl.core.types.Predicate;
|
||||||
|
|
||||||
|
public interface UserGroupQuerydslPredicateRepository extends JpaRepository<UserGroup, Long>, QuerydslPredicateExecutor<UserGroup> {
|
||||||
|
|
||||||
|
default List<UserGroup> findAllWithNameInAnyList(List<String> names1, List<String> names2) {
|
||||||
|
return StreamSupport
|
||||||
|
.stream(findAll(predicateInAnyList(names1, names2)).spliterator(), false)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
default Predicate predicateInAnyList(List<String> names1, List<String> names2) {
|
||||||
|
return new BooleanBuilder().and(QUserGroup.userGroup.name.in(names1))
|
||||||
|
.or(QUserGroup.userGroup.name.in(names2));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,270 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria;
|
||||||
|
|
||||||
|
import static com.baeldung.querydslvsjpacriteria.entities.GroupUser_.tasks;
|
||||||
|
import static com.baeldung.querydslvsjpacriteria.entities.QGroupUser.groupUser;
|
||||||
|
import static com.baeldung.querydslvsjpacriteria.entities.QTask.task;
|
||||||
|
import static com.baeldung.querydslvsjpacriteria.entities.QUserGroup.userGroup;
|
||||||
|
import static com.baeldung.querydslvsjpacriteria.entities.UserGroup_.GROUP_USERS;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.GroupUser;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.Task;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.UserGroup;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.entities.UserGroup_;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.repositories.UserGroupJpaSpecificationRepository;
|
||||||
|
import com.baeldung.querydslvsjpacriteria.repositories.UserGroupQuerydslPredicateRepository;
|
||||||
|
import com.querydsl.core.Tuple;
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.EntityManagerFactory;
|
||||||
|
import jakarta.persistence.Persistence;
|
||||||
|
import jakarta.persistence.TypedQuery;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||||
|
import jakarta.persistence.criteria.JoinType;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
|
|
||||||
|
@EnableJpaRepositories(basePackages = {"com.baeldung.querydslvsjpacriteria.repositories"})
|
||||||
|
@ContextConfiguration("/test-context.xml")
|
||||||
|
@ExtendWith({SpringExtension.class, TimingExtension.class})
|
||||||
|
class QuerydslVSJPACriteriaIntegrationTest {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(QuerydslVSJPACriteriaIntegrationTest.class);
|
||||||
|
|
||||||
|
private static EntityManagerFactory emf;
|
||||||
|
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
|
private JPAQueryFactory queryFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserGroupJpaSpecificationRepository userGroupJpaSpecificationRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserGroupQuerydslPredicateRepository userQuerydslPredicateRepository;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void populateDatabase() {
|
||||||
|
emf = Persistence.createEntityManagerFactory("com.baeldung.querydsl.intro");
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
Stream.of("Group 1", "Group 2", "Group 3")
|
||||||
|
.forEach(g -> {
|
||||||
|
UserGroup userGroup = new UserGroup();
|
||||||
|
userGroup.setName(g);
|
||||||
|
em.persist(userGroup);
|
||||||
|
IntStream.range(0, 10)
|
||||||
|
.forEach(u -> {
|
||||||
|
GroupUser groupUser = new GroupUser();
|
||||||
|
groupUser.setLogin("User" + u);
|
||||||
|
groupUser.getUserGroups().add(userGroup);
|
||||||
|
em.persist(groupUser);
|
||||||
|
userGroup.getGroupUsers().add(groupUser);
|
||||||
|
IntStream.range(0, 10000)
|
||||||
|
.forEach(t -> {
|
||||||
|
Task task = new Task();
|
||||||
|
task.setDescription(groupUser.getLogin() + " task #" + t);
|
||||||
|
task.setUser(groupUser);
|
||||||
|
em.persist(task);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
em.merge(userGroup);
|
||||||
|
});
|
||||||
|
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
em = emf.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
queryFactory = new JPAQueryFactory(em);
|
||||||
|
|
||||||
|
createUserGroup("Group 1");
|
||||||
|
createUserGroup("Group 4");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJpaCriteria_whenGetAllTheUserGroups_thenExpectedNumberOfItemsShouldBePresent() {
|
||||||
|
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<UserGroup> cr = cb.createQuery(UserGroup.class);
|
||||||
|
Root<UserGroup> root = cr.from(UserGroup.class);
|
||||||
|
CriteriaQuery<UserGroup> select = cr.select(root);
|
||||||
|
|
||||||
|
TypedQuery<UserGroup> query = em.createQuery(select);
|
||||||
|
List<UserGroup> results = query.getResultList();
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenQueryDSL_whenGetAllTheUserGroups_thenExpectedNumberOfItemsShouldBePresent() {
|
||||||
|
List<UserGroup> results = queryFactory.selectFrom(userGroup).fetch();
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJpaCriteria_whenGetTheUserGroups_thenExpectedAggregatedDataShouldBePresent() {
|
||||||
|
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Object[]> cr = cb.createQuery(Object[].class);
|
||||||
|
Root<UserGroup> root = cr.from(UserGroup.class);
|
||||||
|
|
||||||
|
CriteriaQuery<Object[]> select = cr
|
||||||
|
.multiselect(root.get(UserGroup_.name), cb.countDistinct(root.get(UserGroup_.id)))
|
||||||
|
.where(cb.or(
|
||||||
|
root.get(UserGroup_.name).in("Group 1", "Group 2"),
|
||||||
|
root.get(UserGroup_.name).in("Group 4", "Group 5")
|
||||||
|
))
|
||||||
|
.orderBy(cb.desc(root.get(UserGroup_.name)))
|
||||||
|
.groupBy(root.get(UserGroup_.name));
|
||||||
|
|
||||||
|
TypedQuery<Object[]> query = em.createQuery(select);
|
||||||
|
List<Object[]> results = query.getResultList();
|
||||||
|
assertEquals(2, results.size());
|
||||||
|
assertEquals("Group 2", results.get(0)[0]);
|
||||||
|
assertEquals(1L, results.get(0)[1]);
|
||||||
|
assertEquals("Group 1", results.get(1)[0]);
|
||||||
|
assertEquals(1L, results.get(1)[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenQueryDSL_whenGetTheUserGroups_thenExpectedAggregatedDataShouldBePresent() {
|
||||||
|
List<Tuple> results = queryFactory
|
||||||
|
.select(userGroup.name, userGroup.id.countDistinct())
|
||||||
|
.from(userGroup)
|
||||||
|
.where(userGroup.name.in("Group 1", "Group 2")
|
||||||
|
.or(userGroup.name.in("Group 4", "Group 5")))
|
||||||
|
.orderBy(userGroup.name.desc())
|
||||||
|
.groupBy(userGroup.name)
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
assertEquals(2, results.size());
|
||||||
|
assertEquals("Group 2", results.get(0).get(userGroup.name));
|
||||||
|
assertEquals(1L, results.get(0).get(userGroup.id.countDistinct()));
|
||||||
|
assertEquals("Group 1", results.get(1).get(userGroup.name));
|
||||||
|
assertEquals(1L, results.get(1).get(userGroup.id.countDistinct()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJpaCriteria_whenGetTheUserGroupsWithJoins_thenExpectedDataShouldBePresent() {
|
||||||
|
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<UserGroup> query = cb.createQuery(UserGroup.class);
|
||||||
|
|
||||||
|
query.from(UserGroup.class)
|
||||||
|
.<UserGroup, GroupUser>join(GROUP_USERS, JoinType.LEFT)
|
||||||
|
.join(tasks, JoinType.LEFT);
|
||||||
|
|
||||||
|
List<UserGroup> result = em.createQuery(query).getResultList();
|
||||||
|
assertUserGroups(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertUserGroups(List<UserGroup> userGroups) {
|
||||||
|
assertEquals(3, userGroups.size());
|
||||||
|
for (UserGroup group : userGroups) {
|
||||||
|
assertEquals(10, group.getGroupUsers().size());
|
||||||
|
for (GroupUser user : group.getGroupUsers()) {
|
||||||
|
assertEquals(10000, user.getTasks().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenQueryDSL_whenGetTheUserGroupsWithJoins_thenExpectedDataShouldBePresent() {
|
||||||
|
List<UserGroup> result = queryFactory
|
||||||
|
.selectFrom(userGroup)
|
||||||
|
.leftJoin(userGroup.groupUsers, groupUser)
|
||||||
|
.leftJoin(groupUser.tasks, task)
|
||||||
|
.fetch();
|
||||||
|
|
||||||
|
assertUserGroups(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJpaCriteria_whenModifyTheUserGroup_thenNameShouldBeUpdated() {
|
||||||
|
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||||
|
CriteriaUpdate<UserGroup> criteriaUpdate = cb.createCriteriaUpdate(UserGroup.class);
|
||||||
|
Root<UserGroup> root = criteriaUpdate.from(UserGroup.class);
|
||||||
|
criteriaUpdate.set(UserGroup_.name, "Group 1 Updated using Jpa Criteria");
|
||||||
|
criteriaUpdate.where(cb.equal(root.get(UserGroup_.name), "Group 1"));
|
||||||
|
|
||||||
|
em.createQuery(criteriaUpdate).executeUpdate();
|
||||||
|
UserGroup foundGroup = em.find(UserGroup.class, 1L);
|
||||||
|
assertEquals("Group 1 Updated using Jpa Criteria", foundGroup.getName());
|
||||||
|
renameEntityBack(foundGroup, "Group 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renameEntityBack(UserGroup foundGroup, String name) {
|
||||||
|
foundGroup.setName(name);
|
||||||
|
em.merge(foundGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenQueryDSL_whenModifyTheUserGroup_thenNameShouldBeUpdated() {
|
||||||
|
queryFactory.update(userGroup)
|
||||||
|
.set(userGroup.name, "Group 1 Updated Using QueryDSL")
|
||||||
|
.where(userGroup.name.eq("Group 1"))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
UserGroup foundGroup = em.find(UserGroup.class, 1L);
|
||||||
|
assertEquals("Group 1 Updated Using QueryDSL", foundGroup.getName());
|
||||||
|
renameEntityBack(foundGroup, "Group 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJpaSpecificationRepository_whenGetTheUserGroups_thenExpectedDataShouldBePresent() {
|
||||||
|
List<UserGroup> results = userGroupJpaSpecificationRepository.findAllWithNameInAnyList(
|
||||||
|
List.of("Group 1", "Group 2"), List.of("Group 4", "Group 5"));
|
||||||
|
|
||||||
|
assertEquals(2, results.size());
|
||||||
|
assertEquals("Group 1", results.get(0).getName());
|
||||||
|
assertEquals("Group 4", results.get(1).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenQuerydslPredicateRepository_whenGetTheUserGroups_thenExpectedDataShouldBePresent() {
|
||||||
|
List<UserGroup> results = userQuerydslPredicateRepository.findAllWithNameInAnyList(
|
||||||
|
List.of("Group 1", "Group 2"), List.of("Group 4", "Group 5"));
|
||||||
|
|
||||||
|
assertEquals(2, results.size());
|
||||||
|
assertEquals("Group 1", results.get(0).getName());
|
||||||
|
assertEquals("Group 4", results.get(1).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createUserGroup(String name) {
|
||||||
|
UserGroup entity = new UserGroup();
|
||||||
|
entity.setName(name);
|
||||||
|
userGroupJpaSpecificationRepository.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
userGroupJpaSpecificationRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void afterClass() {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.querydslvsjpacriteria;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
|
||||||
|
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TimingExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(TimingExtension.class);
|
||||||
|
private static final String START_TIME = "start time";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTestExecution(ExtensionContext context) {
|
||||||
|
getStore(context).put(START_TIME, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTestExecution(ExtensionContext context) {
|
||||||
|
Method testMethod = context.getRequiredTestMethod();
|
||||||
|
long startTime = getStore(context).remove(START_TIME, long.class);
|
||||||
|
long duration = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
logger.info(String.format("Method [%s] took %s ms.", testMethod.getName(), duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Store getStore(ExtensionContext context) {
|
||||||
|
return context.getStore(Namespace.create(getClass(), context.getRequiredTestMethod()));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user