diff --git a/README.md b/README.md
index 2c99daa..87c49d4 100644
--- a/README.md
+++ b/README.md
@@ -99,7 +99,7 @@ You can find the sample code from: https://github.com/tdilber/spring-jpa-dynamic
io.github.tdilber
spring-boot-starter-jpa-dynamic-query
- 0.1.0
+ 0.2.0
```
@@ -108,7 +108,7 @@ You can find the sample code from: https://github.com/tdilber/spring-jpa-dynamic
io.github.tdilber
spring-jpa-dynamic-query
- 0.4.0
+ 0.5.0
```
@@ -169,7 +169,7 @@ more multi value operators with java code touches.
#### Comparable Operators
-This operator is used to compare numbers and dates. Available Java Types are **Date, Double, Long, LocalDate,
+This operator is used to compare numbers and dates. Available Java Types are **Timestamp, Date, Double, Long, LocalDate,
ZonedDateTime, Instant, Integer**.
The following operators are available:
diff --git a/pom.xml b/pom.xml
index ca0cb4c..37b0084 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
io.github.tdilber
spring-boot-starter-jpa-dynamic-query
- 0.1.0
+ 0.2.0
jar
Spring Jpa Dynamic Query
Spring Jpa Dynamic Query (JDQ) Project
diff --git a/src/main/java/com/beyt/jdq/exception/DynamicQueryIllegalArgumentException.java b/src/main/java/com/beyt/jdq/exception/DynamicQueryIllegalArgumentException.java
new file mode 100644
index 0000000..fe506a0
--- /dev/null
+++ b/src/main/java/com/beyt/jdq/exception/DynamicQueryIllegalArgumentException.java
@@ -0,0 +1,20 @@
+package com.beyt.jdq.exception;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Created by tdilber at 14-Seo-2024
+ */
+@Slf4j
+public class DynamicQueryIllegalArgumentException extends IllegalArgumentException {
+
+ public DynamicQueryIllegalArgumentException(String errorMessage) {
+ super(errorMessage);
+ log.error(errorMessage, this);
+ }
+
+ public DynamicQueryIllegalArgumentException(String errorMessage, Throwable err) {
+ super(errorMessage, err);
+ log.error(errorMessage, err);
+ }
+}
diff --git a/src/main/java/com/beyt/jdq/query/DynamicQueryManager.java b/src/main/java/com/beyt/jdq/query/DynamicQueryManager.java
index 469ef7c..50b5c93 100644
--- a/src/main/java/com/beyt/jdq/query/DynamicQueryManager.java
+++ b/src/main/java/com/beyt/jdq/query/DynamicQueryManager.java
@@ -6,6 +6,7 @@
import com.beyt.jdq.dto.Criteria;
import com.beyt.jdq.dto.DynamicQuery;
import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.exception.DynamicQueryIllegalArgumentException;
import com.beyt.jdq.query.rule.specification.*;
import com.beyt.jdq.repository.DynamicSpecificationRepositoryImpl;
import com.beyt.jdq.util.ApplicationContextUtil;
@@ -33,6 +34,7 @@
import jakarta.persistence.criteria.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.lang.reflect.RecordComponent;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -171,6 +173,9 @@ private static void extractIfJdqModel(DynamicQuery dynamicQuery, Cl
List> select = new ArrayList<>();
for (Field declaredField : resultTypeClass.getDeclaredFields()) {
if (declaredField.isAnnotationPresent(JdqIgnoreField.class)) {
+ if (resultTypeClass.isRecord()) {
+ throw new DynamicQueryIllegalArgumentException("Record class can not have @JdqIgnoreField annotation");
+ }
continue;
}
@@ -307,27 +312,38 @@ protected static long executeCountQuery(TypedQuery query) {
protected static Iterable convertResultToResultTypeList(List> querySelects, Class resultTypeClass, Iterable entityListBySelectableFilter, boolean isPage) {
Map setterMethods = new HashMap<>();
- for (int i = 0; i < querySelects.size(); i++) {
- String select = querySelects.get(i).getSecond();
+ if (!resultTypeClass.isRecord()) {
+ for (int i = 0; i < querySelects.size(); i++) {
+ String select = querySelects.get(i).getSecond();
- Optional methodOptional = Arrays.stream(resultTypeClass.getMethods())
- .filter(c -> c.getName().equalsIgnoreCase("set" + select)
- && c.getParameterCount() == 1).findFirst();
+ Optional methodOptional = Arrays.stream(resultTypeClass.getMethods())
+ .filter(c -> c.getName().equalsIgnoreCase("set" + select)
+ && c.getParameterCount() == 1).findFirst();
- if (methodOptional.isPresent()) {
- setterMethods.put(i, methodOptional.get());
+ if (methodOptional.isPresent()) {
+ setterMethods.put(i, methodOptional.get());
+ }
}
}
Stream stream = isPage ? ((Page) entityListBySelectableFilter).stream() : ((List) entityListBySelectableFilter).stream();
List resultTypeList = stream.map(t -> {
try {
- ResultType resultObj = resultTypeClass.getConstructor().newInstance();
-
- for (Map.Entry entry : setterMethods.entrySet()) {
- entry.getValue().invoke(resultObj, t.get(entry.getKey()));
+ if (resultTypeClass.isRecord()) {
+ Object[] args = new Object[querySelects.size()];
+ for (int i = 0; i < querySelects.size(); i++) {
+ args[i] = t.get(i);
+ }
+ return resultTypeClass.getDeclaredConstructor(Arrays.stream(resultTypeClass.getRecordComponents())
+ .map(RecordComponent::getType)
+ .toArray(Class[]::new)).newInstance(args);
+ } else {
+ ResultType resultObj = resultTypeClass.getConstructor().newInstance();
+ for (Map.Entry entry : setterMethods.entrySet()) {
+ entry.getValue().invoke(resultObj, t.get(entry.getKey()));
+ }
+ return resultObj;
}
- return resultObj;
} catch (Exception e) {
return null;
}
diff --git a/src/main/java/com/beyt/jdq/util/ApplicationContextUtil.java b/src/main/java/com/beyt/jdq/util/ApplicationContextUtil.java
index ebb3da1..80a655a 100644
--- a/src/main/java/com/beyt/jdq/util/ApplicationContextUtil.java
+++ b/src/main/java/com/beyt/jdq/util/ApplicationContextUtil.java
@@ -10,14 +10,9 @@
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
- private static IEntityManagerProvider entityManagerProvider;
- private static IDeserializer deserializer;
-
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtil.applicationContext = applicationContext;
- ApplicationContextUtil.entityManagerProvider = applicationContext.getBean(IEntityManagerProvider.class);
- ApplicationContextUtil.deserializer = applicationContext.getBean(IDeserializer.class);
}
public static ApplicationContext getApplicationContext() {
@@ -25,10 +20,10 @@ public static ApplicationContext getApplicationContext() {
}
public static EntityManager getEntityManager(){
- return entityManagerProvider.provide();
+ return applicationContext.getBean(IEntityManagerProvider.class).provide();
}
public static IDeserializer getDeserializer() {
- return deserializer;
+ return applicationContext.getBean(IDeserializer.class);
}
}
diff --git a/src/main/java/com/beyt/jdq/util/field/FieldUtil.java b/src/main/java/com/beyt/jdq/util/field/FieldUtil.java
index 54275c0..e190da0 100644
--- a/src/main/java/com/beyt/jdq/util/field/FieldUtil.java
+++ b/src/main/java/com/beyt/jdq/util/field/FieldUtil.java
@@ -9,6 +9,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.sql.Timestamp;
/**
* Created by tdilber at 11/17/2020
@@ -25,6 +26,7 @@ private FieldUtil() {
fieldHelperMap.put(String.class, new StringFieldHelper());
fieldHelperMap.put(Boolean.class, new BooleanFieldHelper());
fieldHelperMap.put(Date.class, new DateFieldHelper());
+ fieldHelperMap.put(Timestamp.class, new TimestampFieldHelper());
fieldHelperMap.put(Double.class, new DoubleFieldHelper());
fieldHelperMap.put(Long.class, new LongFieldHelper());
fieldHelperMap.put(LocalDate.class, new LocalDateFieldHelper());
diff --git a/src/main/java/com/beyt/jdq/util/field/helper/TimestampFieldHelper.java b/src/main/java/com/beyt/jdq/util/field/helper/TimestampFieldHelper.java
new file mode 100644
index 0000000..42d1932
--- /dev/null
+++ b/src/main/java/com/beyt/jdq/util/field/helper/TimestampFieldHelper.java
@@ -0,0 +1,34 @@
+package com.beyt.jdq.util.field.helper;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.sql.Timestamp;
+
+/**
+ * Created by tdilber at 11/17/2020
+ */
+@Slf4j
+public class TimestampFieldHelper implements IFieldHelper {
+ @Override
+ public Timestamp fillRandom() {
+ return new Timestamp(System.currentTimeMillis() + random.nextInt(1000000000));
+ }
+
+ @Override
+ public Timestamp fillValue(String value) {
+ DateFormat dateFormat = new SimpleDateFormat();
+ try {
+ return new Timestamp(dateFormat.parse(value).getTime());
+ } catch (ParseException e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public String createGeneratorCode(String value) {
+ return "new Timestamp(" + fillValue(value).getTime() + "L)";
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/BaseTestInstance.java b/src/test/java/com/beyt/jdq/BaseTestInstance.java
index e5b3204..95c72d1 100644
--- a/src/test/java/com/beyt/jdq/BaseTestInstance.java
+++ b/src/test/java/com/beyt/jdq/BaseTestInstance.java
@@ -2,12 +2,20 @@
import com.beyt.jdq.testenv.entity.Customer;
import com.beyt.jdq.testenv.entity.User;
-import com.beyt.jdq.testenv.repository.CustomerRepository;
-import com.beyt.jdq.testenv.repository.UserRepository;
+import com.beyt.jdq.testenv.entity.authorization.*;
+import com.beyt.jdq.testenv.entity.school.Address;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.entity.school.Department;
+import com.beyt.jdq.testenv.entity.school.Student;
+import com.beyt.jdq.testenv.repository.*;
+import org.junit.jupiter.api.BeforeAll;
import org.springframework.beans.factory.annotation.Autowired;
import jakarta.persistence.EntityManager;
import java.util.Calendar;
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Set;
public abstract class BaseTestInstance {
@@ -17,6 +25,31 @@ public abstract class BaseTestInstance {
@Autowired
protected UserRepository userRepository;
+ @Autowired
+ protected AddressRepository addressRepository;
+
+ @Autowired
+ protected RoleRepository roleRepository;
+
+ @Autowired
+ protected DepartmentRepository departmentRepository;
+
+ @Autowired
+ protected CourseRepository courseRepository;
+
+ @Autowired
+ protected StudentRepository studentRepository;
+
+ @Autowired
+ protected AuthorizationRepository authorizationRepository;
+
+ @Autowired
+ protected RoleAuthorizationRepository roleAuthorizationRepository;
+
+ @Autowired
+ protected AdminUserRepository adminUserRepository;
+
+
@Autowired
protected EntityManager entityManager;
@@ -39,6 +72,77 @@ public abstract class BaseTestInstance {
public final Customer customer8;
public static final Calendar INSTANCE = Calendar.getInstance();
+ protected Address address1 = new Address(1L, "123 Main St", "New York", "NY", "10001");
+ protected Address address2 = new Address(2L, "456 Park Ave", "Chicago", "IL", "60605");
+ protected Address address3 = new Address(3L, "789 Broadway", "Los Angeles", "CA", "90001");
+ protected Address address4 = new Address(4L, "321 Market St", "San Francisco", "CA", "94105");
+ protected Address address5 = new Address(5L, "654 Elm St", "Dallas", "TX", "75001");
+ protected Address address6 = new Address(6L, "987 Oak St", "Houston", "TX", "77002");
+ protected Address address7 = new Address(7L, "345 Pine St", "Philadelphia", "PA", "19019");
+ protected Address address8 = new Address(8L, "678 Maple St", "Phoenix", "AZ", "85001");
+ protected Address address9 = new Address(9L, "102 Beach St", "Miami", "FL", "33101");
+ protected Address address10 = new Address(10L, "567 Hill St", "Atlanta", "GA", "30301");
+
+
+ protected Department department1 = new Department(1L, "Computer Science");
+ protected Department department2 = new Department(2L, "Mathematics");
+ protected Department department3 = new Department(3L, "Physics");
+ protected Department department4 = new Department(4L, "Chemistry");
+ protected Department department5 = new Department(5L, "Biology");
+ protected Department department6 = new Department(6L, "English Literature");
+ protected Department department7 = new Department(7L, "History");
+ protected Department department8 = new Department(8L, "Geography");
+ protected Department department9 = new Department(9L, "Political Science");
+ protected Department department10 = new Department(10L, "Economics");
+
+ protected Course course1 = new Course(1L, "Introduction to Computer Science", Timestamp.valueOf("2016-06-18 00:00:00"), 50, true, "Introduction to fundamental concepts of computer science.");
+ protected Course course2 = new Course(2L, "Calculus I", Timestamp.valueOf("2017-06-18 00:00:00"), 60, true, "Introduction to fundamental concepts of calculus.");
+ protected Course course3 = new Course(3L, "Calculus II", Timestamp.valueOf("2018-06-18 00:00:00"), 250, null, "Advanced topics in calculus including integrals and series.");
+ protected Course course4 = new Course(4L, "Physics I", Timestamp.valueOf("2019-06-18 00:00:00"), 250, null, "Introduction to classical mechanics and Newtonian physics.");
+ protected Course course5 = new Course(5L, "Physics II", Timestamp.valueOf("2020-06-18 00:00:00"), 250, null, "Advanced topics in physics including electromagnetism and thermodynamics.");
+ protected Course course6 = new Course(6L, "Chemistry I", Timestamp.valueOf("2021-06-18 00:00:00"), 40, null, "Basic principles of chemistry including atomic structure and chemical bonding.");
+ protected Course course7 = new Course(7L, "Chemistry II", Timestamp.valueOf("2022-06-18 00:00:00"), 30, null, "Continuation of chemistry studies covering topics like kinetics and equilibrium.");
+ protected Course course8 = new Course(8L, "Biology I", Timestamp.valueOf("2015-06-18 00:00:00"), 20, true, "Introduction to cellular biology and genetics.");
+ protected Course course9 = new Course(9L, "Biology II", Timestamp.valueOf("2013-06-18 00:00:00"), 54, true, "Advanced topics in biology including evolution and ecology.");
+ protected Course course10 = new Course(10L, "English Literature I", Timestamp.valueOf("2025-06-18 00:00:00"), 10, false, "Exploration of classic works of English literature and literary analysis.");
+
+ protected Student student1 = new Student(1L, "John Doe", address1, department1, List.of(course1, course2));
+ protected Student student2 = new Student(2L, "Jane Smith", address2, department2, List.of(course2, course4));
+ protected Student student3 = new Student(3L, "Robert Johnson", address3, department3, List.of(course3));
+ protected Student student4 = new Student(4L, "Emily Davis", address4, department4, List.of(course4));
+ protected Student student5 = new Student(5L, "Michael Miller", address5, department5, List.of(course5));
+ protected Student student6 = new Student(6L, "Sarah Wilson", address6, department6, List.of(course6));
+ protected Student student7 = new Student(7L, "David Moore", address7, department7, List.of(course7));
+ protected Student student8 = new Student(8L, "Jessica Taylor", address8, department8, List.of(course8));
+ protected Student student9 = new Student(9L, "Daniel Anderson", address9, department9, List.of(course9));
+ protected Student student10 = new Student(10L, "Jennifer Thomas", address10, department10, List.of(course10));
+ protected Student student11 = new Student(11L, "Talha Dilber", null, null, List.of());
+
+ protected Authorization authorization1 = new Authorization(1L, "auth1", "/url1", "icon1");
+ protected Authorization authorization2 = new Authorization(2L, "auth2", "/url2", "icon2");
+ protected Authorization authorization3 = new Authorization(3L, "auth3", "/url3", "icon3");
+ protected Authorization authorization4 = new Authorization(4L, "auth4", "/url4", "icon4");
+ protected Authorization authorization5 = new Authorization(5L, "auth5", "/url5", "icon5");
+
+ protected Role role1 = new Role(1L, "role1", "description1");
+ protected Role role2 = new Role(2L, "role2", "description2");
+ protected Role role3 = new Role(3L, "role3", "description3");
+ protected Role role4 = new Role(4L, "role4", "description4");
+ protected Role role5 = new Role(5L, "role5", "description5");
+
+ protected RoleAuthorization roleAuthorization1 = new RoleAuthorization(1L, role1, authorization1);
+ protected RoleAuthorization roleAuthorization2 = new RoleAuthorization(2L, role2, authorization2);
+ protected RoleAuthorization roleAuthorization3 = new RoleAuthorization(3L, role3, authorization3);
+ protected RoleAuthorization roleAuthorization4 = new RoleAuthorization(4L, role4, authorization4);
+ protected RoleAuthorization roleAuthorization5 = new RoleAuthorization(5L, role5, authorization5);
+
+
+ protected AdminUser adminUser1 = new AdminUser(1L, "admin1", "password1", List.of(role1));
+ protected AdminUser adminUser2 = new AdminUser(2L, "admin2", "password2", List.of(role2));
+ protected AdminUser adminUser3 = new AdminUser(3L, "admin3", "password3", List.of(role3));
+ protected AdminUser adminUser4 = new AdminUser(4L, "admin4", "password4", List.of(role4));
+ protected AdminUser adminUser5 = new AdminUser(5L, "admin5", "password5", List.of(role5));
+
public BaseTestInstance() {
user1 = new User(null, "Name 1", "Surname 1", 35, INSTANCE.toInstant(), User.Status.PASSIVE, User.Type.USER);
customer1 = new Customer(null, "Customer 1", 20, INSTANCE.toInstant(), user1);
@@ -65,4 +169,55 @@ public BaseTestInstance() {
customer8 = new Customer(null, null, 27, INSTANCE.toInstant(), user8);
}
+
+
+ @BeforeAll
+ public void init() {
+ if (userRepository.count() != 0) {
+ return;
+ }
+ userRepository.save(user1);
+ userRepository.save(user2);
+ userRepository.save(user3);
+ userRepository.save(user4);
+ userRepository.save(user5);
+ userRepository.save(user6);
+ userRepository.save(user7);
+ userRepository.save(user8);
+
+ if (customerRepository.count() != 0) {
+ return;
+ }
+ customerRepository.save(customer1);
+ customerRepository.save(customer2);
+ customerRepository.save(customer3);
+ customerRepository.save(customer4);
+ customerRepository.save(customer5);
+ customerRepository.save(customer6);
+ customerRepository.save(customer7);
+ customerRepository.save(customer8);
+
+ if (addressRepository.count() != 0) {
+ return;
+ }
+ addressRepository.saveAllAndFlush(List.of(address1, address2, address3, address4, address5, address6, address7, address8, address9, address10));
+
+ departmentRepository.saveAllAndFlush(List.of(department1, department2, department3, department4, department5, department6, department7, department8, department9, department10));
+
+ courseRepository.saveAllAndFlush(List.of(course1, course2, course3, course4, course5, course6, course7, course8, course9, course10));
+
+ studentRepository.saveAllAndFlush(List.of(student1, student2, student3, student4, student5, student6, student7, student8, student9, student10, student11));
+
+ if (authorizationRepository.count() != 0) {
+ return;
+ }
+ authorizationRepository.saveAllAndFlush(List.of(authorization1, authorization2, authorization3, authorization4, authorization5));
+
+ roleRepository.saveAllAndFlush(List.of(role1, role2, role3, role4, role5));
+
+ roleAuthorizationRepository.saveAllAndFlush(List.of(roleAuthorization1, roleAuthorization2, roleAuthorization3, roleAuthorization4, roleAuthorization5));
+
+ adminUserRepository.saveAllAndFlush(List.of(adminUser1, adminUser2, adminUser3, adminUser4, adminUser5));
+ }
+
}
diff --git a/src/test/java/com/beyt/jdq/context/DBSelectionContext.java b/src/test/java/com/beyt/jdq/context/DBSelectionContext.java
new file mode 100644
index 0000000..83178a9
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/context/DBSelectionContext.java
@@ -0,0 +1,21 @@
+package com.beyt.jdq.context;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+import java.io.Serializable;
+
+
+@Component
+@RequestScope
+public class DBSelectionContext implements Serializable {
+ public enum Database {
+ READ, WRITE
+ }
+
+ @Getter
+ @Setter
+ private Database database = Database.WRITE;
+}
diff --git a/src/test/java/com/beyt/jdq/controller/PresentationTestController.java b/src/test/java/com/beyt/jdq/controller/PresentationTestController.java
new file mode 100644
index 0000000..17ea9ea
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/controller/PresentationTestController.java
@@ -0,0 +1,44 @@
+package com.beyt.jdq.controller;
+
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.DynamicQuery;
+import com.beyt.jdq.presetation.S9_Query_Builder;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.repository.AdminUserRepository;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/test-api")
+public class PresentationTestController {
+ @Autowired
+ private CourseRepository courseRepository;
+ @Autowired
+ private AdminUserRepository adminUserRepository;
+
+
+ @GetMapping("/course")
+ public ResponseEntity> getCourseWithCriteria(CriteriaList criteriaList) {
+ List customerList = courseRepository.findAll(criteriaList);
+ return ResponseEntity.ok().body(customerList);
+ }
+
+ @GetMapping("/course/as-page")
+ public ResponseEntity> getCourseWithSearchFilterAsPage(DynamicQuery dynamicQuery) {
+ Page customerList = courseRepository.findAllAsPage(dynamicQuery);
+ return ResponseEntity.ok().body(customerList);
+ }
+
+ @GetMapping("/course/as-list")
+ public ResponseEntity> getCourseWithSearchFilterAsList(DynamicQuery dynamicQuery) {
+ List customerList = adminUserRepository.findAll(dynamicQuery, S9_Query_Builder.AuthorizationSummary.class);
+ return ResponseEntity.ok().body(customerList);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/deserializer/DateTimeDeserializer.java b/src/test/java/com/beyt/jdq/deserializer/DateTimeDeserializer.java
new file mode 100644
index 0000000..aa1fcf8
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/deserializer/DateTimeDeserializer.java
@@ -0,0 +1,39 @@
+package com.beyt.jdq.deserializer;
+
+import org.springframework.stereotype.Component;
+
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.sql.Timestamp;
+import java.util.Date;
+
+@Component
+public class DateTimeDeserializer extends BasicDeserializer {
+
+ @Override
+ public T deserialize(Object value, Class clazz) throws Exception {
+ if (clazz.isAssignableFrom(Date.class)) {
+ if (value instanceof Date date) {
+ return (T) date;
+ }
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ simpleDateFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
+ Date parsedDate = simpleDateFormat.parse(value.toString());
+ return (T) parsedDate;
+ }
+
+ if (clazz.isAssignableFrom(Timestamp.class)) {
+ if (value instanceof Timestamp date) {
+ return (T) date;
+ }
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ simpleDateFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
+ Date parsedDate = simpleDateFormat.parse(value.toString());
+ return (T) new Timestamp(parsedDate.getTime());
+ }
+
+
+
+ return super.deserialize(value, clazz);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/interceptor/DatabaseSelectionInterceptor.java b/src/test/java/com/beyt/jdq/interceptor/DatabaseSelectionInterceptor.java
new file mode 100644
index 0000000..1fa71e9
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/interceptor/DatabaseSelectionInterceptor.java
@@ -0,0 +1,35 @@
+package com.beyt.jdq.interceptor;
+
+import com.beyt.jdq.context.DBSelectionContext;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+@Slf4j
+public class DatabaseSelectionInterceptor implements HandlerInterceptor {
+
+ @Autowired
+ private DBSelectionContext dbSelectionContext;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ if (!(handler instanceof HandlerMethod)) {
+ return true;
+ }
+
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ GetMapping getMapping = method.getAnnotation(GetMapping.class);
+ if (getMapping != null) {
+ dbSelectionContext.setDatabase(DBSelectionContext.Database.READ);
+ }
+
+ return true;
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S10_Argument_Resolvers.java b/src/test/java/com/beyt/jdq/presetation/S10_Argument_Resolvers.java
new file mode 100644
index 0000000..9d551ab
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S10_Argument_Resolvers.java
@@ -0,0 +1,98 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.TestUtil;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.util.PresentationUtil;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@AutoConfigureMockMvc
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S10_Argument_Resolvers extends BaseTestInstance {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ private static final String COURSE_SEARCH_LIST_API_URL = "/test-api/course/as-list";
+ private static final String COURSE_CRITERIA_API_URL = "/test-api/course";
+
+
+ @Test
+ public void argumentCriteriaListTests() throws Exception {
+// List.of(course1, course2, course3, course4, course5, course6, course7, course8, course9, course10);
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=name&operation0=CONTAIN&values0=Calculus", Course[].class, List.of(course2, course3));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=name&operation0=DOES_NOT_CONTAIN&values0=I", Course[].class, List.of());
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=name&operation0=END_WITH&values0=Science", Course[].class, List.of(course1));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=name&operation0=START_WITH&values0=Physics", Course[].class, List.of(course4, course5));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=active&operation0=SPECIFIED&values0=true", Course[].class, List.of(course1, course2, course8, course9, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=active&operation0=SPECIFIED&values0=false", Course[].class, List.of(course3, course4, course5, course6, course7));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=name&operation0=EQUAL&values0=Calculus I", Course[].class, List.of(course2));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=startDate&operation0=EQUAL&values0=2015-06-18", Course[].class, List.of());
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=maxStudentCount&operation0=EQUAL&values0=54", Course[].class, List.of(course9));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=name&operation0=NOT_EQUAL&values0=Introduction to Computer Science", Course[].class, List.of(course2, course3, course4, course5, course6, course7, course8, course9, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=id&operation0=GREATER_THAN&values0=5", Course[].class, List.of(course6, course7, course8, course9, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=startDate&operation0=GREATER_THAN&values0=2015-06-18", Course[].class, List.of(course1, course2, course3, course4, course5, course6, course7, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=id&operation0=GREATER_THAN_OR_EQUAL&values0=8", Course[].class, List.of(course8, course9, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=startDate&operation0=GREATER_THAN_OR_EQUAL&values0=2019-06-18", Course[].class, List.of(course5, course6, course7, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=maxStudentCount&operation0=LESS_THAN&values0=40", Course[].class, List.of(course7, course8, course10));
+ printRequestedResultAndAssert(COURSE_CRITERIA_API_URL,
+ "key0=maxStudentCount&operation0=LESS_THAN_OR_EQUAL&values0=40", Course[].class, List.of(course6, course7, course8, course10));
+ }
+
+
+ @Test
+ public void argumentSearchQueryTests() throws Exception {
+ printRequestedResultAndAssert(COURSE_SEARCH_LIST_API_URL,
+ "select0=id&select1=username&select2=roles.id&select3=roles.name&select4=roles.roleAuthorizations.authorization.id&select5=roles.roleAuthorizations.authorization.name&select6=roles.roleAuthorizations.authorization.menuIcon&" +
+ "selectAs0=adminId&selectAs1=adminUsername&selectAs2=roleId&selectAs3=roleName&selectAs4=authorizationId&selectAs5=authorizationName&selectAs6=menuIcon&" +
+ "orderBy0=roles.id&orderByDirection0=desc&" +
+ "page=1&" +
+ "pageSize=2&" +
+ "key0=roles.roleAuthorizations.authorization.menuIcon&operation0=START_WITH&values0=icon", S9_Query_Builder.AuthorizationSummary[].class, List.of(new S9_Query_Builder.AuthorizationSummary(3L, "admin3", 3L, "role3", 3L, "auth3", "icon3"), new S9_Query_Builder.AuthorizationSummary(2L, "admin2", 2L, "role2", 2L, "auth2", "icon2")));
+ }
+
+ private void printRequestedResultAndAssert(String apiUrl, String filter, Class clazz, Object result) throws Exception {
+ MvcResult mvcResult = mockMvc.perform(get(apiUrl + "?" + filter))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)).andReturn();
+
+ PresentationUtil.prettyPrint(TestUtil.getResultListValue(mvcResult.getResponse().getContentAsString(), clazz));
+
+ assertEquals(result, TestUtil.getResultListValue(mvcResult.getResponse().getContentAsString(), clazz));
+ }
+
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S11_Additional_Features.java b/src/test/java/com/beyt/jdq/presetation/S11_Additional_Features.java
new file mode 100644
index 0000000..20dcd6e
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S11_Additional_Features.java
@@ -0,0 +1,57 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.TestUtil;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S11_Additional_Features extends BaseTestInstance {
+ private @Autowired CourseRepository courseRepository;
+
+
+ @Test
+ public void consumePartially() {
+ List courses = new ArrayList<>();
+ courseRepository.consumePartially((courseList) -> {
+ courseList.forEach(course -> {
+ System.out.println(course.getName());
+ });
+ System.out.println("Consumed partially");
+ courses.addAll(courseList);
+ }, 2);
+
+ assertEquals(List.of(course1, course2, course3, course4, course5, course6, course7, course8, course9, course10), courses);
+ }
+
+ @Test
+ public void consumePartially2() {
+ List courses = new ArrayList<>();
+ CriteriaList criteriaList = CriteriaList.of(Criteria.of("id", CriteriaOperator.GREATER_THAN, 5));
+ courseRepository.consumePartially(criteriaList, (courseList) -> {
+ courseList.forEach(course -> {
+ System.out.println(course.getName());
+ });
+ System.out.println("Consumed partially");
+ courses.addAll(courseList);
+ }, 2);
+ assertEquals(List.of(course6, course7, course8, course9, course10), courses);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S1_Operators.java b/src/test/java/com/beyt/jdq/presetation/S1_Operators.java
new file mode 100644
index 0000000..da94d22
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S1_Operators.java
@@ -0,0 +1,197 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.User;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import com.beyt.jdq.testenv.repository.DepartmentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@Slf4j
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S1_Operators extends BaseTestInstance {
+ private @Autowired CourseRepository courseRepository;
+ private @Autowired DepartmentRepository departmentRepository;
+
+
+//CONTAIN
+//DOES_NOT_CONTAIN
+//END_WITH
+//START_WITH
+//SPECIFIED
+//EQUAL
+//NOT_EQUAL
+//GREATER_THAN
+//GREATER_THAN_OR_EQUAL
+//LESS_THAN
+//LESS_THAN_OR_EQUAL
+
+ @Test
+ public void contain() {
+ var criteriaList = CriteriaList.of(Criteria.of("name", CriteriaOperator.CONTAIN, "Calculus"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+
+ assertEquals(new ArrayList<>(List.of(course2, course3)), courseList);
+ }
+
+ @Test
+ public void doesNotContain() {
+ var criteriaList = CriteriaList.of(Criteria.of("name", CriteriaOperator.DOES_NOT_CONTAIN, "I"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(), courseList);
+ }
+
+ @Test
+ public void endWith() {
+ var criteriaList = CriteriaList.of(Criteria.of("name", CriteriaOperator.END_WITH, "Science"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course1), courseList);
+ }
+
+ @Test
+ public void startWith() {
+ var criteriaList = CriteriaList.of(Criteria.of("name", CriteriaOperator.START_WITH, "Physics"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course4, course5), courseList);
+ }
+
+ @Test
+ public void specifiedTrue() {
+ var criteriaList = CriteriaList.of(Criteria.of("active", CriteriaOperator.SPECIFIED, "true"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course1, course2, course8, course9, course10), courseList);
+ }
+
+
+
+ @Test
+ public void specifiedFalse() {
+ var criteriaList = CriteriaList.of(Criteria.of("active", CriteriaOperator.SPECIFIED, "false"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course3, course4, course5, course6, course7), courseList);
+ }
+
+ @Test
+ public void equal() {
+ var criteriaList = CriteriaList.of(Criteria.of("name", CriteriaOperator.EQUAL, "Calculus I"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course2), courseList);
+ }
+
+ @SneakyThrows
+ @Test
+ public void equalDate() {
+ var criteriaList = CriteriaList.of(Criteria.of("startDate", CriteriaOperator.EQUAL, "2015-06-18"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(), courseList);
+ }
+
+ @SneakyThrows
+ @Test
+ public void equalInteger() {
+ var criteriaList = CriteriaList.of(Criteria.of("maxStudentCount", CriteriaOperator.EQUAL, 54));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//9
+ assertEquals(List.of(course9), courseList);
+ }
+
+ @Test
+ public void notEqual() {
+ var criteriaList = CriteriaList.of(Criteria.of("name", CriteriaOperator.NOT_EQUAL, "Introduction to Computer Science"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList); //2,3,4,5,6,7,8,9,10
+ assertEquals(List.of(course2, course3, course4, course5, course6, course7, course8, course9, course10), courseList);
+ }
+
+ @Test
+ public void greaterThan() {
+ var criteriaList = CriteriaList.of(Criteria.of("id", CriteriaOperator.GREATER_THAN, 5));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course6, course7, course8, course9, course10), courseList);
+ }
+
+ @Test
+ public void greaterThanDate() {
+ var criteriaList = CriteriaList.of(Criteria.of("startDate", CriteriaOperator.GREATER_THAN, "2015-06-18"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList); //1,2,3,4,5,6,7,10
+ assertEquals(List.of(course1, course2, course3, course4, course5, course6, course7, course10), courseList);
+ }
+
+ @Test
+ public void greaterThanOrEqual() {
+ var criteriaList = CriteriaList.of(Criteria.of("id", CriteriaOperator.GREATER_THAN_OR_EQUAL, 8));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//8,9,10
+ assertEquals(List.of(course8, course9, course10), courseList);
+ }
+
+ @Test
+ public void greaterThanOrEqualDate() {
+ var criteriaList = CriteriaList.of(Criteria.of("startDate", CriteriaOperator.GREATER_THAN_OR_EQUAL, "2019-06-18"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//5.6.7.10
+ assertEquals(List.of(course5, course6, course7, course10), courseList);
+ }
+
+ @Test
+ public void lessThan() {
+ var criteriaList = CriteriaList.of(Criteria.of(Course.Fields.maxStudentCount, CriteriaOperator.LESS_THAN, 40));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course7, course8, course10), courseList);
+ }
+
+ @Test
+ public void lessThanOrEqual() {
+ var criteriaList = CriteriaList.of(Criteria.of(Course.Fields.maxStudentCount, CriteriaOperator.LESS_THAN_OR_EQUAL, 40));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList); // 6,7,8,10
+ assertEquals(List.of(course6, course7, course8, course10), courseList);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S2_Multi_Value_Operators.java b/src/test/java/com/beyt/jdq/presetation/S2_Multi_Value_Operators.java
new file mode 100644
index 0000000..4dbfcc1
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S2_Multi_Value_Operators.java
@@ -0,0 +1,69 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import com.beyt.jdq.testenv.repository.DepartmentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@Slf4j
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S2_Multi_Value_Operators extends BaseTestInstance {
+ private @Autowired CourseRepository courseRepository;
+ private @Autowired DepartmentRepository departmentRepository;
+
+
+ @Test
+ public void equal() {
+ var criteriaList = CriteriaList.of(Criteria.of(Course.Fields.name, CriteriaOperator.EQUAL, "Calculus I", "Calculus II"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList); //2,3
+ assertEquals(List.of(course2, course3), courseList);
+ }
+
+ @Test
+ public void equalInteger() {
+ var criteriaList = CriteriaList.of(Criteria.of(Course.Fields.maxStudentCount, CriteriaOperator.EQUAL, 40, 50));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//1,6
+ assertEquals(List.of(course1, course6), courseList);
+ }
+
+ @Test
+ public void notEqual() {
+ var criteriaList = CriteriaList.of(Criteria.of(Course.Fields.name, CriteriaOperator.NOT_EQUAL, "Calculus I", "Calculus II"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//1,4,5,6,7,8,9,10
+ assertEquals(Arrays.asList(course1, course4, course5, course6, course7, course8, course9, course10), courseList);
+ }
+
+ @Test
+ public void notEqualDate() {
+ var criteriaList = CriteriaList.of(Criteria.of(Course.Fields.startDate, CriteriaOperator.NOT_EQUAL, "2013-06-18", "2015-06-18", "2016-06-18"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S3_AND_OR_Operator.java b/src/test/java/com/beyt/jdq/presetation/S3_AND_OR_Operator.java
new file mode 100644
index 0000000..92616cf
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S3_AND_OR_Operator.java
@@ -0,0 +1,91 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import com.beyt.jdq.testenv.repository.DepartmentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@Slf4j
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S3_AND_OR_Operator extends BaseTestInstance {
+ private @Autowired CourseRepository courseRepository;
+ private @Autowired DepartmentRepository departmentRepository;
+
+
+ @Test
+ public void and() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of(Course.Fields.name, CriteriaOperator.CONTAIN, "II"),
+ Criteria.of(Course.Fields.id, CriteriaOperator.GREATER_THAN, 5));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList); // 7 , 9
+ assertEquals(List.of(course7, course9), courseList);
+ }
+
+
+ @Test
+ public void and2() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of(Course.Fields.name, CriteriaOperator.CONTAIN, "II"),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 7, 8, 9, 10),
+ Criteria.of(Course.Fields.active, CriteriaOperator.SPECIFIED, false));
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList); // 7
+ assertEquals(List.of(course7), courseList);
+ }
+
+
+ @Test
+ public void or() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of(Course.Fields.name, CriteriaOperator.CONTAIN, "II"),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 7, 8, 9, 10),
+ Criteria.of(Course.Fields.active, CriteriaOperator.SPECIFIED, false),
+ Criteria.OR(),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 1, 2, 3, 4, 5),
+ Criteria.of(Course.Fields.id, CriteriaOperator.LESS_THAN, 3)
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//1,2,7
+ assertEquals(List.of(course1, course2, course7), courseList);
+ }
+
+
+ @Test
+ public void or2() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of(Course.Fields.name, CriteriaOperator.CONTAIN, "II"),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 7, 8, 9, 10),
+ Criteria.of(Course.Fields.active, CriteriaOperator.SPECIFIED, false),
+ Criteria.OR(),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 1, 2, 3, 4, 5),
+ Criteria.OR(),
+ Criteria.of(Course.Fields.id, CriteriaOperator.LESS_THAN, 3)
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);//1,2,3,4,5,7
+ assertEquals(List.of(course1, course2, course3, course4, course5, course7), courseList);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S4_SCOPE_Operator.java b/src/test/java/com/beyt/jdq/presetation/S4_SCOPE_Operator.java
new file mode 100644
index 0000000..700d247
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S4_SCOPE_Operator.java
@@ -0,0 +1,69 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import com.beyt.jdq.testenv.repository.DepartmentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@Slf4j
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S4_SCOPE_Operator extends BaseTestInstance {
+ private @Autowired CourseRepository courseRepository;
+ private @Autowired DepartmentRepository departmentRepository;
+
+
+ // (A OR B) AND (C OR D)
+ @Test
+ public void scope() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("", CriteriaOperator.PARENTHES,
+ CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 1),
+ Criteria.OR(),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 2))),
+ Criteria.of("", CriteriaOperator.PARENTHES,
+ CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 2),
+ Criteria.OR(),
+ Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 3)))
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course2), courseList);
+ }
+
+
+ @Test
+ public void scopeInsideScope() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("", CriteriaOperator.PARENTHES,
+ CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 1, 2, 3),
+ Criteria.of(Course.Fields.id, CriteriaOperator.NOT_EQUAL, 2),
+ Criteria.OR(),
+ Criteria.of("", CriteriaOperator.PARENTHES,
+ CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.EQUAL, 2),
+ Criteria.of(Course.Fields.id, CriteriaOperator.NOT_EQUAL, 3)))))
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List courseList = courseRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course1, course2, course3), courseList);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S5_Join.java b/src/test/java/com/beyt/jdq/presetation/S5_Join.java
new file mode 100644
index 0000000..5300960
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S5_Join.java
@@ -0,0 +1,118 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.school.Department;
+import com.beyt.jdq.testenv.entity.school.Student;
+import com.beyt.jdq.testenv.repository.DepartmentRepository;
+import com.beyt.jdq.testenv.repository.StudentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S5_Join extends BaseTestInstance {
+ private @Autowired DepartmentRepository departmentRepository;
+ private @Autowired StudentRepository studentRepository;
+
+
+ /**
+ * Inner join with single entity criteria
+ */
+ @Test
+ public void innerJoin() {
+ var criteriaList = CriteriaList.of(Criteria.of("department.name", CriteriaOperator.START_WITH, "P"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List students = studentRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(students);
+ assertEquals(List.of(student3, student9), students);
+ }
+
+ /**
+ * Inner join with multi joined entity criteria
+ */
+ @Test
+ public void innerJoin2() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("department.name", CriteriaOperator.START_WITH, "P"),
+ Criteria.of("department.id", CriteriaOperator.GREATER_THAN, 3)
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List students = studentRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(students);
+ assertEquals(List.of( student9), students);
+ }
+
+ /**
+ * Inner join with different entity criteria
+ */
+ @Test
+ public void innerJoin3() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("department.name", CriteriaOperator.START_WITH, "P"),
+ Criteria.of("name", CriteriaOperator.START_WITH, "Robert")
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List students = studentRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(students);
+ assertEquals(List.of(student3), students);
+ }
+
+ /**
+ * One to many inner join
+ */
+ @Test
+ public void innerJoin4() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("students.id", CriteriaOperator.GREATER_THAN, 3),
+ Criteria.of("id", CriteriaOperator.LESS_THAN, 6)
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List departments = departmentRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(departments);
+ assertEquals(List.of(department4, department5), departments);
+ }
+
+ /**
+ * Many to many inner join
+ */
+ @Test
+ public void innerJoin5() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("courses.maxStudentCount", CriteriaOperator.GREATER_THAN, 100),
+ Criteria.of("id", CriteriaOperator.GREATER_THAN, 3)
+ );
+ PresentationUtil.prettyPrint(criteriaList);
+ List students = studentRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(students);
+ assertEquals(List.of(student4, student5), students);
+ }
+
+ /**
+ * Typical left join with is null check
+ */
+ @Test
+ public void leftJoin() {
+ var criteriaList = CriteriaList.of(
+ Criteria.of("department students = studentRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(students);
+ assertEquals(List.of(student11), students);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S6_Advenced_Join.java b/src/test/java/com/beyt/jdq/presetation/S6_Advenced_Join.java
new file mode 100644
index 0000000..17e0571
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S6_Advenced_Join.java
@@ -0,0 +1,48 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.authorization.AdminUser;
+import com.beyt.jdq.testenv.repository.AdminUserRepository;
+import com.beyt.jdq.testenv.repository.DepartmentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S6_Advenced_Join extends BaseTestInstance {
+ private @Autowired AdminUserRepository adminUserRepository;
+ private @Autowired DepartmentRepository departmentRepository;
+
+ @Test
+ public void roleJoin() {
+ var criteriaList = CriteriaList.of(Criteria.of("roles.roleAuthorizations.authorization.menuIcon", CriteriaOperator.START_WITH, "icon"));
+ PresentationUtil.prettyPrint(criteriaList);
+ List adminUserList = adminUserRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(adminUserList);//1,2,3,4,5
+ assertEquals(List.of(adminUser1, adminUser2, adminUser3, adminUser4, adminUser5), adminUserList);
+ }
+
+ @Test
+ public void roleLeftJoin() {
+ var criteriaList = CriteriaList.of(Criteria.of("roles adminUserList = adminUserRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(adminUserList);
+ assertEquals(List.of(adminUser1, adminUser2, adminUser3, adminUser4, adminUser5), adminUserList);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S7_Select_Distinct_Order.java b/src/test/java/com/beyt/jdq/presetation/S7_Select_Distinct_Order.java
new file mode 100644
index 0000000..e42a91a
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S7_Select_Distinct_Order.java
@@ -0,0 +1,188 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.DynamicQuery;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.dto.enums.Order;
+
+import jakarta.persistence.Tuple;
+
+import com.beyt.jdq.testenv.entity.school.Course;
+import com.beyt.jdq.testenv.entity.school.Student;
+import com.beyt.jdq.testenv.repository.CourseRepository;
+import com.beyt.jdq.testenv.repository.StudentRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.data.util.Pair;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S7_Select_Distinct_Order extends BaseTestInstance {
+ private @Autowired CourseRepository courseRepository;
+ private @Autowired StudentRepository studentRepository;
+
+
+ @Test
+ public void selectSameObject() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getSelect().add(Pair.of("name", "name"));
+ dynamicQuery.getSelect().add(Pair.of("description", "description"));
+ dynamicQuery.setWhere(CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.GREATER_THAN, 8)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List courseList = courseRepository.findAll(dynamicQuery);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(Course.of(course9.getName(), course9.getDescription()), Course.of(course10.getName(), course10.getDescription())), courseList);
+ }
+
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class CourseName {
+ @Getter
+ @Setter
+ private String name;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof CourseName that)) return false;
+ return Objects.equals(name, that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name);
+ }
+ }
+
+ public record CourseNameRecord(String name) {
+ }
+
+ @Test
+ public void selectDifferentObject() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getSelect().add(Pair.of("name", "name"));
+ dynamicQuery.setWhere(CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.GREATER_THAN, 8)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List courseList = courseRepository.findAll(dynamicQuery, CourseName.class);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(new CourseName(course9.getName()), new CourseName(course10.getName())), courseList);
+
+ List courseListRecord = courseRepository.findAll(dynamicQuery, CourseNameRecord.class);
+ PresentationUtil.prettyPrint(courseListRecord);
+ assertEquals(List.of(new CourseNameRecord(course9.getName()), new CourseNameRecord(course10.getName())), courseListRecord);
+ }
+
+ @Test
+ public void selectDifferentObjectDifferent() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getSelect().add(Pair.of("description", "name"));
+ dynamicQuery.setWhere(CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.GREATER_THAN, 8)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List courseList = courseRepository.findAll(dynamicQuery, CourseName.class);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(new CourseName(course9.getDescription()), new CourseName(course10.getDescription())), courseList);
+
+ List courseListRecord = courseRepository.findAll(dynamicQuery, CourseNameRecord.class);
+ PresentationUtil.prettyPrint(courseListRecord);
+ assertEquals(List.of(new CourseNameRecord(course9.getDescription()), new CourseNameRecord(course10.getDescription())), courseListRecord);
+ }
+
+ @Test
+ public void selectDifferentEntityObject() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getSelect().add(Pair.of("description", "name"));
+ dynamicQuery.setWhere(CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.GREATER_THAN, 8)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List courseList = courseRepository.findAll(dynamicQuery, Student.class);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(Student.of(course9.getDescription()), Student.of(course10.getDescription())), courseList);
+ }
+
+ @Test
+ public void distinct() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+// dynamicQuery.setDistinct(true);
+ dynamicQuery.setWhere(CriteriaList.of(Criteria.of("courses.id", CriteriaOperator.GREATER_THAN, 1), Criteria.of("id", CriteriaOperator.EQUAL, 2)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List studentList = studentRepository.findAll(dynamicQuery);
+ PresentationUtil.prettyPrint(studentList);
+// assertEquals(List.of(student2, student2), studentList); // NEW JPA Behavior CHANGED
+ dynamicQuery.setDistinct(true);
+ studentList = studentRepository.findAll(dynamicQuery);
+ assertEquals(List.of(student2), studentList);
+ }
+
+ @Test
+ public void orderBy() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.setOrderBy(List.of(Pair.of(Course.Fields.id, Order.DESC)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List courseList = courseRepository.findAll(dynamicQuery);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course10, course9, course8, course7, course6, course5, course4, course3, course2, course1), courseList);
+ }
+
+
+ @Test
+ public void orderByMulti() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.setOrderBy(List.of(Pair.of(Course.Fields.maxStudentCount, Order.DESC), Pair.of(Course.Fields.id, Order.DESC)));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List courseList = courseRepository.findAll(dynamicQuery);
+ PresentationUtil.prettyPrint(courseList);
+ assertEquals(List.of(course5, course4, course3, course2, course9, course1, course6, course7, course8, course10), courseList);
+ }
+
+ @Test
+ public void page() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.setWhere(CriteriaList.of(Criteria.of(Course.Fields.id, CriteriaOperator.GREATER_THAN, 3)));
+ dynamicQuery.setPageSize(2);
+ dynamicQuery.setPageNumber(1);
+ System.out.println("Page");
+ Page allAsPage = courseRepository.findAllAsPage(dynamicQuery);
+ PresentationUtil.prettyPrint(courseRepository.findAllAsPage(dynamicQuery));
+ assertEquals(2, allAsPage.getContent().size());
+ assertEquals(List.of(course6, course7), allAsPage.getContent());
+
+
+ System.out.println("Page With Projection");
+ dynamicQuery.getSelect().add(Pair.of("name", "name"));
+ Page courseNames = courseRepository.findAllAsPage(dynamicQuery, CourseName.class);
+ PresentationUtil.prettyPrint(courseNames);
+ assertEquals(2, courseNames.getContent().size());
+ assertEquals(List.of(new CourseName(course6.getName()), new CourseName(course7.getName())), courseNames.getContent());
+
+ System.out.println("Page With Projection Record");
+ Page courseNameRecords = courseRepository.findAllAsPage(dynamicQuery, CourseNameRecord.class);
+ PresentationUtil.prettyPrint(courseNameRecords);
+ assertEquals(2, courseNameRecords.getContent().size());
+ assertEquals(List.of(new CourseNameRecord(course6.getName()), new CourseNameRecord(course7.getName())), courseNameRecords.getContent());
+
+ System.out.println("Tuple");
+ List allAsTuple = courseRepository.findAllAsTuple(dynamicQuery);
+ assertEquals(2, allAsTuple.size());
+ System.out.println("Tuple Page");
+ Page allAsTuplePage = courseRepository.findAllAsTuplePage(dynamicQuery);
+ assertEquals(2, allAsTuplePage.getContent().size());
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S8_Advenced_Projection.java b/src/test/java/com/beyt/jdq/presetation/S8_Advenced_Projection.java
new file mode 100644
index 0000000..130c5b4
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S8_Advenced_Projection.java
@@ -0,0 +1,136 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.annotation.model.JdqField;
+import com.beyt.jdq.annotation.model.JdqModel;
+import com.beyt.jdq.dto.Criteria;
+import com.beyt.jdq.dto.CriteriaList;
+import com.beyt.jdq.dto.DynamicQuery;
+import com.beyt.jdq.dto.enums.CriteriaOperator;
+import com.beyt.jdq.testenv.entity.authorization.AdminUser;
+import com.beyt.jdq.testenv.repository.AdminUserRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.util.Pair;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S8_Advenced_Projection extends BaseTestInstance {
+ private @Autowired AdminUserRepository adminUserRepository;
+
+
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class AuthorizationSummary {
+ @Getter @Setter private Long adminId;
+ @Getter @Setter private String adminUsername;
+ @Getter @Setter private Long roleId;
+ @Getter @Setter private String roleName;
+ @Getter @Setter private Long authorizationId;
+ @Getter @Setter private String authorizationName;
+ @Getter @Setter private String menuIcon;
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AuthorizationSummary that)) return false;
+ return Objects.equals(adminId, that.adminId) && Objects.equals(adminUsername, that.adminUsername) && Objects.equals(roleId, that.roleId) && Objects.equals(roleName, that.roleName) && Objects.equals(authorizationId, that.authorizationId) && Objects.equals(authorizationName, that.authorizationName) && Objects.equals(menuIcon, that.menuIcon);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(adminId, adminUsername, roleId, roleName, authorizationId, authorizationName, menuIcon);
+ }
+ }
+ @Test
+ public void roleJoin() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getSelect().add(Pair.of("id", "adminId"));
+ dynamicQuery.getSelect().add(Pair.of("username", "adminUsername"));
+ dynamicQuery.getSelect().add(Pair.of("roles.id", "roleId"));
+ dynamicQuery.getSelect().add(Pair.of("roles.name", "roleName"));
+ dynamicQuery.getSelect().add(Pair.of("roles.roleAuthorizations.authorization.id", "authorizationId"));
+ dynamicQuery.getSelect().add(Pair.of("roles.roleAuthorizations.authorization.name", "authorizationName"));
+ dynamicQuery.getSelect().add(Pair.of("roles.roleAuthorizations.authorization.menuIcon", "menuIcon"));
+ var criteriaList = CriteriaList.of(Criteria.of("roles.roleAuthorizations.authorization.menuIcon", CriteriaOperator.START_WITH, "icon"));
+ dynamicQuery.getWhere().addAll(criteriaList);
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List result = adminUserRepository.findAll(criteriaList);
+ PresentationUtil.prettyPrint(result);
+ assertEquals(List.of(adminUser1, adminUser2, adminUser3, adminUser4, adminUser5), result);
+
+ List result2 = adminUserRepository.findAll(dynamicQuery, AuthorizationSummary.class);
+ PresentationUtil.prettyPrint(result2);
+
+ assertEquals(List.of(new AuthorizationSummary(1L, "admin1", 1L, "role1", 1L, "auth1", "icon1"),
+ new AuthorizationSummary(2L, "admin2", 2L, "role2", 2L, "auth2", "icon2"),
+ new AuthorizationSummary(3L, "admin3", 3L, "role3", 3L, "auth3", "icon3"),
+ new AuthorizationSummary(4L, "admin4", 4L, "role4", 4L, "auth4", "icon4"),
+ new AuthorizationSummary(5L, "admin5", 5L, "role5", 5L, "auth5", "icon5")), result2);
+ }
+
+
+ @JdqModel // DONT MISS THIS ANNOTATION
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class AnnotatedAuthorizationSummary {
+ @JdqField("id")
+ @Getter @Setter
+ private Long adminId;
+ @JdqField("username")
+ @Getter @Setter private String adminUsername;
+ @JdqField("roles.id")
+ @Getter @Setter private Long roleId;
+ @JdqField("roles.name")
+ @Getter @Setter private String roleName;
+ @JdqField("roles.roleAuthorizations.authorization.id")
+ @Getter @Setter private Long authorizationId;
+ @JdqField("roles.roleAuthorizations.authorization.name")
+ @Getter @Setter private String authorizationName;
+ @JdqField("roles.roleAuthorizations.authorization.menuIcon")
+ @Getter @Setter private String menuIcon;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AnnotatedAuthorizationSummary that)) return false;
+ return Objects.equals(adminId, that.adminId) && Objects.equals(adminUsername, that.adminUsername) && Objects.equals(roleId, that.roleId) && Objects.equals(roleName, that.roleName) && Objects.equals(authorizationId, that.authorizationId) && Objects.equals(authorizationName, that.authorizationName) && Objects.equals(menuIcon, that.menuIcon);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(adminId, adminUsername, roleId, roleName, authorizationId, authorizationName, menuIcon);
+ }
+ }
+
+ @Test
+ public void roleJoinWithAnnotatedModel() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getWhere().add(Criteria.of("roles.roleAuthorizations.authorization.menuIcon", CriteriaOperator.START_WITH, "icon"));
+ PresentationUtil.prettyPrint(dynamicQuery);
+ List result2 = adminUserRepository.findAll(dynamicQuery, AnnotatedAuthorizationSummary.class);
+ PresentationUtil.prettyPrint(result2);
+
+ assertEquals(List.of(new AnnotatedAuthorizationSummary(1L, "admin1", 1L, "role1", 1L, "auth1", "icon1"),
+ new AnnotatedAuthorizationSummary(2L, "admin2", 2L, "role2", 2L, "auth2", "icon2"),
+ new AnnotatedAuthorizationSummary(3L, "admin3", 3L, "role3", 3L, "auth3", "icon3"),
+ new AnnotatedAuthorizationSummary(4L, "admin4", 4L, "role4", 4L, "auth4", "icon4"),
+ new AnnotatedAuthorizationSummary(5L, "admin5", 5L, "role5", 5L, "auth5", "icon5")), result2);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/presetation/S9_Query_Builder.java b/src/test/java/com/beyt/jdq/presetation/S9_Query_Builder.java
new file mode 100644
index 0000000..431053c
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/presetation/S9_Query_Builder.java
@@ -0,0 +1,79 @@
+package com.beyt.jdq.presetation;
+
+import com.beyt.jdq.BaseTestInstance;
+import com.beyt.jdq.TestApplication;
+import com.beyt.jdq.dto.enums.Order;
+import com.beyt.jdq.testenv.repository.AdminUserRepository;
+import com.beyt.jdq.util.PresentationUtil;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.test.annotation.DirtiesContext;
+
+import java.util.List;
+import java.util.Objects;
+
+import static com.beyt.jdq.query.builder.QuerySimplifier.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@SpringBootTest(classes = TestApplication.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class S9_Query_Builder extends BaseTestInstance {
+ private @Autowired AdminUserRepository adminUserRepository;
+
+
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class AuthorizationSummary {
+ @Getter
+ @Setter
+ private Long adminId;
+ @Getter @Setter private String adminUsername;
+ @Getter @Setter private Long roleId;
+ @Getter @Setter private String roleName;
+ @Getter @Setter private Long authorizationId;
+ @Getter @Setter private String authorizationName;
+ @Getter @Setter private String menuIcon;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AuthorizationSummary that)) return false;
+ return Objects.equals(adminId, that.adminId) && Objects.equals(adminUsername, that.adminUsername) && Objects.equals(roleId, that.roleId) && Objects.equals(roleName, that.roleName) && Objects.equals(authorizationId, that.authorizationId) && Objects.equals(authorizationName, that.authorizationName) && Objects.equals(menuIcon, that.menuIcon);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(adminId, adminUsername, roleId, roleName, authorizationId, authorizationName, menuIcon);
+ }
+ }
+ @Test
+ public void queryBuilder() {
+ Page result = adminUserRepository.queryBuilder()
+ .select(Select("id", "adminId"),
+ Select("username", "adminUsername"),
+ Select("roles.id", "roleId"),
+ Select("roles.name", "roleName"),
+ Select("roles.roleAuthorizations.authorization.id", "authorizationId"),
+ Select("roles.roleAuthorizations.authorization.name", "authorizationName"),
+ Select("roles.roleAuthorizations.authorization.menuIcon", "menuIcon"))
+ .distinct(false)
+ .where(Field("roles.roleAuthorizations.authorization.menuIcon").startWith("icon"), Parantesis(Field("id").eq(3), OR, Field("roles.id").eq(4), OR, Field("id").eq(5)), Parantesis(Field("id").eq(5), OR, Field("id").eq(4), OR, Field("roles.id").eq(3)))
+ .orderBy(OrderBy("roles.id", Order.DESC))
+ .page(1, 2)
+ .getResultAsPage(AuthorizationSummary.class);
+
+ PresentationUtil.prettyPrint(result);
+
+
+ assertEquals(List.of(new AuthorizationSummary(3L, "admin3", 3L, "role3", 3L, "auth3", "icon3")), result.getContent());
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/query/DynamicQueryManagerTest.java b/src/test/java/com/beyt/jdq/query/DynamicQueryManagerTest.java
index cb7a8f3..9254350 100644
--- a/src/test/java/com/beyt/jdq/query/DynamicQueryManagerTest.java
+++ b/src/test/java/com/beyt/jdq/query/DynamicQueryManagerTest.java
@@ -21,6 +21,7 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.util.Pair;
+import org.springframework.test.annotation.DirtiesContext;
import jakarta.persistence.Tuple;
import java.text.SimpleDateFormat;
@@ -33,31 +34,11 @@
@SpringBootTest(classes = TestApplication.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class DynamicQueryManagerTest extends BaseTestInstance {
private SimpleDateFormat dateFormat;
- @BeforeAll
- protected void init() {
- userRepository.save(user1);
- userRepository.save(user2);
- userRepository.save(user3);
- userRepository.save(user4);
- userRepository.save(user5);
- userRepository.save(user6);
- userRepository.save(user7);
- userRepository.save(user8);
-
- customerRepository.save(customer1);
- customerRepository.save(customer2);
- customerRepository.save(customer3);
- customerRepository.save(customer4);
- customerRepository.save(customer5);
- customerRepository.save(customer6);
- customerRepository.save(customer7);
- customerRepository.save(customer8);
- }
-
@Test
void test() {
@@ -268,6 +249,25 @@ void JdqModels() {
assertEquals(toList(new UserJdqModel(customer7.getName(), customer7.getUser().getName(), customer7.getAge(), null), new UserJdqModel(customer8.getName(), customer8.getUser().getName(), customer8.getAge(), null)), result);
}
+ @JdqModel
+ public record UserJdqModelRecord(@JdqField("name") String nameButDifferentFieldName, @JdqField("user.name") String userNameWithJoin, Integer age) {
+ }
+
+ @JdqModel
+ public record UserJdqModelRecordNotValid(@JdqField("name") String nameButDifferentFieldName, @JdqField("user.name") String userNameWithJoin, @JdqIgnoreField Integer age) {
+ }
+
+ @Test
+ void JdqModelRecord() {
+ DynamicQuery dynamicQuery = new DynamicQuery();
+ dynamicQuery.getWhere().add(Criteria.of("age", CriteriaOperator.GREATER_THAN, 25));
+
+
+ List result = customerRepository.findAll(dynamicQuery, UserJdqModelRecord.class);
+ assertEquals(toList(new UserJdqModelRecord(customer7.getName(), customer7.getUser().getName(), customer7.getAge()), new UserJdqModelRecord(customer8.getName(), customer8.getUser().getName(), customer8.getAge())), result);
+ assertThrows(Exception.class, () -> customerRepository.findAll(dynamicQuery, UserJdqModelRecordNotValid.class));
+ }
+
@Test
void simplifiedSearchQuery() {
List result = customerRepository.queryBuilder()
diff --git a/src/test/java/com/beyt/jdq/resolver/ArgumentResolversTests.java b/src/test/java/com/beyt/jdq/resolver/ArgumentResolversTests.java
index 292ee8b..1ce6f8d 100644
--- a/src/test/java/com/beyt/jdq/resolver/ArgumentResolversTests.java
+++ b/src/test/java/com/beyt/jdq/resolver/ArgumentResolversTests.java
@@ -37,28 +37,6 @@ public class ArgumentResolversTests extends BaseTestInstance {
private static final String USER_SEARCH_LIST_API_URL = "/test-api/user/as-list";
private static final String USER_SEARCH_PAGE_API_URL = "/test-api/user/as-page";
- @BeforeAll
- private void init() {
- userRepository.save(user1);
- userRepository.save(user2);
- userRepository.save(user3);
- userRepository.save(user4);
- userRepository.save(user5);
- userRepository.save(user6);
- userRepository.save(user7);
- userRepository.save(user8);
-
- customerRepository.save(customer1);
- customerRepository.save(customer2);
- customerRepository.save(customer3);
- customerRepository.save(customer4);
- customerRepository.save(customer5);
- customerRepository.save(customer6);
- customerRepository.save(customer7);
- customerRepository.save(customer8);
- }
-
-
@Test
public void argumentCriteriaListTests() throws Exception {
/* CONTAIN
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/authorization/AdminUser.java b/src/test/java/com/beyt/jdq/testenv/entity/authorization/AdminUser.java
new file mode 100644
index 0000000..59c38c7
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/authorization/AdminUser.java
@@ -0,0 +1,47 @@
+package com.beyt.jdq.testenv.entity.authorization;
+
+import jakarta.persistence.*;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+@Getter
+@Setter
+@ToString
+@Entity
+@Table(name = "admin_user")
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
+public class AdminUser {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String username;
+
+ private String password;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable(
+ name = "admin_user_role",
+ joinColumns = @JoinColumn(name = "admin_user_id"),
+ inverseJoinColumns = @JoinColumn(name = "role_id"))
+ List roles;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AdminUser adminUser)) return false;
+ return Objects.equals(id, adminUser.id) && Objects.equals(username, adminUser.username) && Objects.equals(password, adminUser.password);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, username, password);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/authorization/Authorization.java b/src/test/java/com/beyt/jdq/testenv/entity/authorization/Authorization.java
new file mode 100644
index 0000000..4b7e65a
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/authorization/Authorization.java
@@ -0,0 +1,58 @@
+package com.beyt.jdq.testenv.entity.authorization;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.*;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+
+import java.util.Objects;
+import java.util.Set;
+
+@Getter
+@Setter
+@ToString
+@Entity
+@Table(name = "my_authorization")
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
+public class Authorization {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
+
+ @Column(name = "menu_url")
+ private String menuUrl;
+
+ @Column(name = "menu_icon")
+ private String menuIcon;
+
+ public Authorization(Long id, String name, String menuUrl, String menuIcon) {
+ this.id = id;
+ this.name = name;
+ this.menuUrl = menuUrl;
+ this.menuIcon = menuIcon;
+ }
+
+ @JsonIgnore
+ @ToString.Exclude
+ @OneToMany(mappedBy = "authorization", fetch = FetchType.LAZY)
+ Set roleAuthorizations;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Authorization that)) return false;
+ return Objects.equals(id, that.id) && Objects.equals(name, that.name) && Objects.equals(menuUrl, that.menuUrl) && Objects.equals(menuIcon, that.menuIcon);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, menuUrl, menuIcon);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/authorization/Role.java b/src/test/java/com/beyt/jdq/testenv/entity/authorization/Role.java
new file mode 100644
index 0000000..7ed54ac
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/authorization/Role.java
@@ -0,0 +1,48 @@
+package com.beyt.jdq.testenv.entity.authorization;
+
+import jakarta.persistence.*;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+
+import java.util.Objects;
+import java.util.Set;
+
+@Getter
+@Setter
+@ToString
+@Entity
+@Table(name = "role")
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
+public class Role {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
+
+ private String description;
+
+ public Role(Long id, String name, String description) {
+ this.id = id;
+ this.name = name;
+ this.description = description;
+ }
+
+ @OneToMany(mappedBy = "role", fetch = FetchType.EAGER)
+ Set roleAuthorizations;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Role role)) return false;
+ return Objects.equals(id, role.id) && Objects.equals(name, role.name) && Objects.equals(description, role.description);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, description);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/authorization/RoleAuthorization.java b/src/test/java/com/beyt/jdq/testenv/entity/authorization/RoleAuthorization.java
new file mode 100644
index 0000000..1139d57
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/authorization/RoleAuthorization.java
@@ -0,0 +1,49 @@
+// RoleAuthorization.java
+package com.beyt.jdq.testenv.entity.authorization;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.*;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import java.util.Objects;
+
+@Getter
+@Setter
+@ToString
+@Entity
+@Table(name = "role_authorization")
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
+public class RoleAuthorization {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @ToString.Exclude
+ @JsonIgnore
+ @ManyToOne
+ @JoinColumn(name = "role_id")
+ private Role role;
+
+ @ManyToOne
+ @Fetch(FetchMode.SELECT)
+ @JoinColumn(name = "authorization_id")
+ private Authorization authorization;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof RoleAuthorization that)) return false;
+ return Objects.equals(id, that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(id);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/school/Address.java b/src/test/java/com/beyt/jdq/testenv/entity/school/Address.java
new file mode 100644
index 0000000..d5edb16
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/school/Address.java
@@ -0,0 +1,54 @@
+package com.beyt.jdq.testenv.entity.school;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.FieldNameConstants;
+
+import java.util.Objects;
+
+@ToString
+@Getter
+@Setter
+@Entity
+@Table(name = "address")
+@NoArgsConstructor
+@FieldNameConstants
+public class Address {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String street;
+ private String city;
+ private String state;
+ private String zip;
+
+ public Address(Long id, String street, String city, String state, String zip) {
+ this.id = id;
+ this.street = street;
+ this.city = city;
+ this.state = state;
+ this.zip = zip;
+ }
+
+ @ToString.Exclude
+ @JsonIgnore
+ @OneToOne(mappedBy = "address", fetch = FetchType.LAZY)
+ private Student student;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Address address)) return false;
+ return Objects.equals(id, address.id) && Objects.equals(street, address.street) && Objects.equals(city, address.city) && Objects.equals(state, address.state) && Objects.equals(zip, address.zip);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, street, city, state, zip);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/school/Course.java b/src/test/java/com/beyt/jdq/testenv/entity/school/Course.java
new file mode 100644
index 0000000..0f241da
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/school/Course.java
@@ -0,0 +1,64 @@
+package com.beyt.jdq.testenv.entity.school;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.*;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+
+import java.sql.Timestamp;
+import java.util.Objects;
+import java.util.Set;
+
+@ToString
+@Getter
+@Setter
+@Entity
+@Table(name = "course")
+@NoArgsConstructor
+@FieldNameConstants
+public class Course {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
+
+ private Timestamp startDate;
+
+ private Integer maxStudentCount;
+
+ private Boolean active;
+
+ private String description;
+
+ public Course(Long id, String name, Timestamp startDate, Integer maxStudentCount, Boolean active, String description) {
+ this.id = id;
+ this.name = name;
+ this.startDate = startDate;
+ this.maxStudentCount = maxStudentCount;
+ this.active = active;
+ this.description = description;
+ }
+
+ public static Course of(String name, String description) {
+ return new Course(null, name, null, null, null, description);
+ }
+
+ @JsonIgnore
+ @ToString.Exclude
+ @ManyToMany(mappedBy = "courses", fetch = FetchType.LAZY)
+ private Set students;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Course course)) return false;
+ return Objects.equals(id, course.id) && Objects.equals(name, course.name) && Objects.equals(startDate, course.startDate) && Objects.equals(maxStudentCount, course.maxStudentCount) && Objects.equals(active, course.active) && Objects.equals(description, course.description);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, startDate, maxStudentCount, active, description);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/school/Department.java b/src/test/java/com/beyt/jdq/testenv/entity/school/Department.java
new file mode 100644
index 0000000..245f065
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/school/Department.java
@@ -0,0 +1,47 @@
+package com.beyt.jdq.testenv.entity.school;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.*;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+
+import java.util.Objects;
+import java.util.Set;
+
+@ToString
+@Getter
+@Setter
+@Entity
+@Table(name = "department")
+@NoArgsConstructor
+@FieldNameConstants
+public class Department {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
+
+ public Department(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @JsonIgnore
+ @ToString.Exclude
+ @OneToMany(mappedBy="department", fetch = FetchType.EAGER)
+ private Set students;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Department that)) return false;
+ return Objects.equals(id, that.id) && Objects.equals(name, that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/entity/school/Student.java b/src/test/java/com/beyt/jdq/testenv/entity/school/Student.java
new file mode 100644
index 0000000..e901be8
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/entity/school/Student.java
@@ -0,0 +1,64 @@
+package com.beyt.jdq.testenv.entity.school;
+
+import jakarta.persistence.*;
+
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+import org.hibernate.annotations.Fetch;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+@ToString
+@Getter
+@Setter
+@Entity
+@Table(name = "student")
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
+public class Student {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
+
+ public Student(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "address_id", referencedColumnName = "id")
+ private Address address;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name="department_id", nullable=true)
+ private Department department;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
+ @JoinTable(
+ name = "StudentCourse",
+ joinColumns = @JoinColumn(name = "student_id"),
+ inverseJoinColumns = @JoinColumn(name = "course_id"))
+ List courses;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof Student student)) return false;
+ return Objects.equals(id, student.id) && Objects.equals(name, student.name);
+ }
+ public static Student of(String name) {
+ Student student = new Student();
+ student.setName(name);
+ return student;
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name);
+ }
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/AddressRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/AddressRepository.java
new file mode 100644
index 0000000..6be484a
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/AddressRepository.java
@@ -0,0 +1,10 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.school.Address;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface AddressRepository extends JpaRepository, JpaDynamicQueryRepository {
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/AdminUserRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/AdminUserRepository.java
new file mode 100644
index 0000000..21de0c9
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/AdminUserRepository.java
@@ -0,0 +1,7 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.authorization.AdminUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AdminUserRepository extends JpaRepository, JpaDynamicQueryRepository {}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/AuthorizationRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/AuthorizationRepository.java
new file mode 100644
index 0000000..6fc1e30
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/AuthorizationRepository.java
@@ -0,0 +1,7 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.authorization.Authorization;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AuthorizationRepository extends JpaRepository, JpaDynamicQueryRepository {}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/CourseRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/CourseRepository.java
new file mode 100644
index 0000000..9723a4e
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/CourseRepository.java
@@ -0,0 +1,9 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.school.Course;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CourseRepository extends JpaDynamicQueryRepository {
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/DepartmentRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/DepartmentRepository.java
new file mode 100644
index 0000000..9b6139b
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/DepartmentRepository.java
@@ -0,0 +1,10 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.school.Department;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface DepartmentRepository extends JpaRepository, JpaDynamicQueryRepository {
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/RoleAuthorizationRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/RoleAuthorizationRepository.java
new file mode 100644
index 0000000..8076060
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/RoleAuthorizationRepository.java
@@ -0,0 +1,7 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.authorization.RoleAuthorization;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface RoleAuthorizationRepository extends JpaRepository, JpaDynamicQueryRepository {}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/RoleRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/RoleRepository.java
new file mode 100644
index 0000000..2e009d5
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/RoleRepository.java
@@ -0,0 +1,7 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.authorization.Role;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface RoleRepository extends JpaRepository, JpaDynamicQueryRepository {}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/StudentRepository.java b/src/test/java/com/beyt/jdq/testenv/repository/StudentRepository.java
new file mode 100644
index 0000000..8952b51
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/testenv/repository/StudentRepository.java
@@ -0,0 +1,10 @@
+package com.beyt.jdq.testenv.repository;
+
+import com.beyt.jdq.repository.JpaDynamicQueryRepository;
+import com.beyt.jdq.testenv.entity.school.Student;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface StudentRepository extends JpaRepository, JpaDynamicQueryRepository {
+}
diff --git a/src/test/java/com/beyt/jdq/testenv/repository/field/FieldUtilTest.java b/src/test/java/com/beyt/jdq/testenv/repository/field/FieldUtilTest.java
index 1db9817..b12d827 100644
--- a/src/test/java/com/beyt/jdq/testenv/repository/field/FieldUtilTest.java
+++ b/src/test/java/com/beyt/jdq/testenv/repository/field/FieldUtilTest.java
@@ -8,7 +8,7 @@
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
-import java.util.Date;
+import java.sql.Timestamp;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -28,7 +28,7 @@ void fillValue() throws ParseException {
assertEquals(Double.parseDouble("155"), FieldUtil.fillValue(Double.class, "155"));
assertEquals(Integer.parseInt("155"), FieldUtil.fillValue(Integer.class, "155"));
assertEquals(Boolean.TRUE, FieldUtil.fillValue(Boolean.class, "True"));
- assertEquals(simpleDateFormat.format(new Date(currentTimeMillis)), simpleDateFormat.format(FieldUtil.fillValue(Date.class, simpleDateFormat.format(new Date(currentTimeMillis)))));
+ assertEquals(simpleDateFormat.format(new Timestamp(currentTimeMillis)), simpleDateFormat.format(FieldUtil.fillValue(Timestamp.class, simpleDateFormat.format(new Timestamp(currentTimeMillis)))));
assertEquals(ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()), FieldUtil.fillValue(ZonedDateTime.class, ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()).toString()));
}
}
diff --git a/src/test/java/com/beyt/jdq/util/PresentationUtil.java b/src/test/java/com/beyt/jdq/util/PresentationUtil.java
new file mode 100644
index 0000000..8b24172
--- /dev/null
+++ b/src/test/java/com/beyt/jdq/util/PresentationUtil.java
@@ -0,0 +1,15 @@
+package com.beyt.jdq.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.SneakyThrows;
+
+public class PresentationUtil {
+
+ @SneakyThrows
+ public static void prettyPrint(Object object) {
+ var objectMapper = new ObjectMapper();
+ System.out.println("______________________________________________________________________________");
+ System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object));
+ System.out.println("========================================================================");
+ }
+}
diff --git a/src/test/resources/config/application.yml b/src/test/resources/config/application.yml
index 18fbf14..f9cf050 100644
--- a/src/test/resources/config/application.yml
+++ b/src/test/resources/config/application.yml
@@ -1,8 +1,13 @@
spring:
+ sql:
+# init:
+# data-locations: classpath:data.sql
+# mode: always
+# schema-locations: classpath:init.sql
application:
name: test-app
datasource:
- url: jdbc:h2:mem:test-app;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+ url: jdbc:h2:mem:test-app;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false
name:
username:
password:
@@ -12,6 +17,7 @@ spring:
serialization:
write-durations-as-timestamps: false
jpa:
+ defer-datasource-initialization: true
database-platform: org.hibernate.dialect.H2Dialect
open-in-view: false
show-sql: true
diff --git a/src/test/resources/config/data.sql b/src/test/resources/config/data.sql
new file mode 100644
index 0000000..b6e5afd
--- /dev/null
+++ b/src/test/resources/config/data.sql
@@ -0,0 +1,111 @@
+-- Insert queries for Address
+INSERT INTO address (id, street, city, state, zip) VALUES (1, '123 Main St', 'New York', 'NY', '10001');
+INSERT INTO address (id, street, city, state, zip) VALUES (2, '456 Park Ave', 'Chicago', 'IL', '60605');
+INSERT INTO address (id, street, city, state, zip) VALUES (3, '789 Broadway', 'Los Angeles', 'CA', '90001');
+INSERT INTO address (id, street, city, state, zip) VALUES (4, '321 Market St', 'San Francisco', 'CA', '94105');
+INSERT INTO address (id, street, city, state, zip) VALUES (5, '654 Elm St', 'Dallas', 'TX', '75001');
+INSERT INTO address (id, street, city, state, zip) VALUES (6, '987 Oak St', 'Houston', 'TX', '77002');
+INSERT INTO address (id, street, city, state, zip) VALUES (7, '345 Pine St', 'Philadelphia', 'PA', '19019');
+INSERT INTO address (id, street, city, state, zip) VALUES (8, '678 Maple St', 'Phoenix', 'AZ', '85001');
+INSERT INTO address (id, street, city, state, zip) VALUES (9, '102 Beach St', 'Miami', 'FL', '33101');
+INSERT INTO address (id, street, city, state, zip) VALUES (10, '567 Hill St', 'Atlanta', 'GA', '30301');
+-- ... repeat for 8 more addresses
+
+-- Insert queries for Department
+INSERT INTO department (id, name) VALUES (1, 'Computer Science');
+INSERT INTO department (id, name) VALUES (2, 'Mathematics');
+INSERT INTO department (id, name) VALUES (3, 'Physics');
+INSERT INTO department (id, name) VALUES (4, 'Chemistry');
+INSERT INTO department (id, name) VALUES (5, 'Biology');
+INSERT INTO department (id, name) VALUES (6, 'English Literature');
+INSERT INTO department (id, name) VALUES (7, 'History');
+INSERT INTO department (id, name) VALUES (8, 'Geography');
+INSERT INTO department (id, name) VALUES (9, 'Political Science');
+INSERT INTO department (id, name) VALUES (10, 'Economics');
+-- ... repeat for 8 more departments
+
+-- Insert queries for Course
+INSERT INTO course (id, name, start_date, max_student_count, active, description)
+VALUES
+ (1, 'Introduction to Computer Science', '2016-06-18', 50, 1, 'Introduction to fundamental concepts of computer science.'),
+ (2, 'Calculus I', '2017-06-18', 60, 1, 'Introduction to fundamental concepts of calculus.'),
+ (3, 'Calculus II', '2018-06-18', 250, null, 'Advanced topics in calculus including integrals and series.'),
+ (4, 'Physics I', '2019-06-18', 250, null, 'Introduction to classical mechanics and Newtonian physics.'),
+ (5, 'Physics II', '2020-06-18', 250, null, 'Advanced topics in physics including electromagnetism and thermodynamics.'),
+ (6, 'Chemistry I', '2021-06-18', 40, null, 'Basic principles of chemistry including atomic structure and chemical bonding.'),
+ (7, 'Chemistry II', '2022-06-18', 30, null, 'Continuation of chemistry studies covering topics like kinetics and equilibrium.'),
+ (8, 'Biology I', '2015-06-18', 20, 1, 'Introduction to cellular biology and genetics.'),
+ (9, 'Biology II', '2013-06-18', 54, 1, 'Advanced topics in biology including evolution and ecology.'),
+ (10, 'English Literature I', '2025-06-18', 10, 0, 'Exploration of classic works of English literature and literary analysis.');
+
+-- ... repeat for 8 more courses
+
+-- Insert queries for Student
+INSERT INTO student (id, name, address_id, department_id) VALUES (1, 'John Doe', 1, 1);
+INSERT INTO student (id, name, address_id, department_id) VALUES (2, 'Jane Smith', 2, 2);
+INSERT INTO student (id, name, address_id, department_id) VALUES (3, 'Robert Johnson', 3, 3);
+INSERT INTO student (id, name, address_id, department_id) VALUES (4, 'Emily Davis', 4, 4);
+INSERT INTO student (id, name, address_id, department_id) VALUES (5, 'Michael Miller', 5, 5);
+INSERT INTO student (id, name, address_id, department_id) VALUES (6, 'Sarah Wilson', 6, 6);
+INSERT INTO student (id, name, address_id, department_id) VALUES (7, 'David Moore', 7, 7);
+INSERT INTO student (id, name, address_id, department_id) VALUES (8, 'Jessica Taylor', 8, 8);
+INSERT INTO student (id, name, address_id, department_id) VALUES (9, 'Daniel Anderson', 9, 9);
+INSERT INTO student (id, name, address_id, department_id) VALUES (10, 'Jennifer Thomas', 10, 10);
+INSERT INTO student (id, name, address_id, department_id) VALUES (11, 'Talha Dilber', null, null);
+-- ... repeat for 8 more students
+
+-- Insert queries for Student_Course
+INSERT INTO student_course (student_id, course_id) VALUES (1, 1);
+INSERT INTO student_course (student_id, course_id) VALUES (1, 2);
+INSERT INTO student_course (student_id, course_id) VALUES (2, 2);
+INSERT INTO student_course (student_id, course_id) VALUES (2, 4);
+INSERT INTO student_course (student_id, course_id) VALUES (3, 3);
+INSERT INTO student_course (student_id, course_id) VALUES (4, 4);
+INSERT INTO student_course (student_id, course_id) VALUES (5, 5);
+INSERT INTO student_course (student_id, course_id) VALUES (6, 6);
+INSERT INTO student_course (student_id, course_id) VALUES (7, 7);
+INSERT INTO student_course (student_id, course_id) VALUES (8, 8);
+INSERT INTO student_course (student_id, course_id) VALUES (9, 9);
+INSERT INTO student_course (student_id, course_id) VALUES (10, 10);
+-- ... repeat for 8 more student-course relationships
+
+-- data.sql
+-- Insert queries for AdminUser
+INSERT INTO admin_user (id, username, password) VALUES (1, 'admin1', 'password1');
+INSERT INTO admin_user (id, username, password) VALUES (2, 'admin2', 'password2');
+INSERT INTO admin_user (id, username, password) VALUES (3, 'admin3', 'password3');
+INSERT INTO admin_user (id, username, password) VALUES (4, 'admin4', 'password4');
+INSERT INTO admin_user (id, username, password) VALUES (5, 'admin5', 'password5');
+-- ... repeat for 9 more admin users
+
+-- Insert queries for Role
+INSERT INTO role (id, name, description) VALUES (1, 'role1', 'description1');
+INSERT INTO role (id, name, description) VALUES (2, 'role2', 'description2');
+INSERT INTO role (id, name, description) VALUES (3, 'role3', 'description3');
+INSERT INTO role (id, name, description) VALUES (4, 'role4', 'description4');
+INSERT INTO role (id, name, description) VALUES (5, 'role5', 'description5');
+
+-- ... repeat for 9 more roles
+
+-- Insert queries for Authorization
+INSERT INTO my_authorization (id, name, menu_url, menu_icon) VALUES (1, 'auth1', '/url1', 'icon1');
+INSERT INTO my_authorization (id, name, menu_url, menu_icon) VALUES (2, 'auth2', '/url2', 'icon2');
+INSERT INTO my_authorization (id, name, menu_url, menu_icon) VALUES (3, 'auth3', '/url3', 'icon3');
+INSERT INTO my_authorization (id, name, menu_url, menu_icon) VALUES (4, 'auth4', '/url4', 'icon4');
+INSERT INTO my_authorization (id, name, menu_url, menu_icon) VALUES (5, 'auth5', '/url5', 'icon5');
+-- ... repeat for 9 more authorizations
+
+-- Insert queries for AdminUserRole
+INSERT INTO admin_user_role (admin_user_id, role_id) VALUES (1, 1);
+INSERT INTO admin_user_role (admin_user_id, role_id) VALUES (2, 2);
+INSERT INTO admin_user_role (admin_user_id, role_id) VALUES (3, 3);
+INSERT INTO admin_user_role (admin_user_id, role_id) VALUES (4, 4);
+INSERT INTO admin_user_role (admin_user_id, role_id) VALUES (5, 5);
+-- ... repeat for 9 more admin user-role relationships
+
+-- Insert queries for RoleAuthorization
+INSERT INTO role_authorization (id, role_id, authorization_id) VALUES (1, 1, 1);
+INSERT INTO role_authorization (id, role_id, authorization_id) VALUES (2, 2, 2);
+INSERT INTO role_authorization (id, role_id, authorization_id) VALUES (3, 3, 3);
+INSERT INTO role_authorization (id, role_id, authorization_id) VALUES (4, 4, 4);
+INSERT INTO role_authorization (id, role_id, authorization_id) VALUES (5, 5, 5);
diff --git a/src/test/resources/config/init.sql b/src/test/resources/config/init.sql
new file mode 100644
index 0000000..0cc6db2
--- /dev/null
+++ b/src/test/resources/config/init.sql
@@ -0,0 +1,73 @@
+CREATE TABLE address (
+ id INT PRIMARY KEY,
+ street VARCHAR(255),
+ city VARCHAR(255),
+ state VARCHAR(2),
+ zip VARCHAR(5)
+);
+
+CREATE TABLE department (
+ id INT PRIMARY KEY,
+ name VARCHAR(255)
+);
+
+CREATE TABLE course (
+ id INT PRIMARY KEY,
+ name VARCHAR(255),
+ start_date DATETIME,
+ max_student_count INT,
+ active BIT,
+ description VARCHAR(255)
+);
+
+CREATE TABLE student (
+ id INT PRIMARY KEY,
+ name VARCHAR(255),
+ address_id INT,
+ department_id INT,
+ FOREIGN KEY (address_id) REFERENCES address(id),
+ FOREIGN KEY (department_id) REFERENCES department(id)
+);
+
+CREATE TABLE student_course (
+ student_id INT,
+ course_id INT,
+ PRIMARY KEY (student_id, course_id),
+ FOREIGN KEY (student_id) REFERENCES student(id),
+ FOREIGN KEY (course_id) REFERENCES course(id)
+);
+
+CREATE TABLE admin_user (
+ id INT PRIMARY KEY,
+ username VARCHAR(255),
+ password VARCHAR(255)
+);
+
+CREATE TABLE role (
+ id INT PRIMARY KEY,
+ name VARCHAR(255),
+ description VARCHAR(255)
+);
+
+CREATE TABLE my_authorization (
+ id INT PRIMARY KEY,
+ name VARCHAR(255),
+ menu_url VARCHAR(255),
+ menu_icon VARCHAR(255)
+);
+
+CREATE TABLE admin_user_role (
+ admin_user_id INT,
+ role_id INT,
+ PRIMARY KEY (admin_user_id, role_id),
+ FOREIGN KEY (admin_user_id) REFERENCES admin_user(id),
+ FOREIGN KEY (role_id) REFERENCES role(id)
+);
+
+CREATE TABLE role_authorization (
+ id INT PRIMARY KEY,
+ role_id INT,
+ authorization_id INT,
+ FOREIGN KEY (role_id) REFERENCES role(id),
+ FOREIGN KEY (authorization_id) REFERENCES my_authorization(id)
+);