Skip to content

Commit f6e5b2d

Browse files
author
talhadilber
committed
Merge branch 'spring-boot-2.x' of https://github.com/tdilber/jpa-generic-criteria-extension into spring-boot-3.x
# Conflicts: # src/test/resources/config/application.yml
2 parents fd80c7c + 154e131 commit f6e5b2d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2262
-70
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ more multi value operators with java code touches.
169169

170170
#### Comparable Operators
171171

172-
This operator is used to compare numbers and dates. Available Java Types are **Date, Double, Long, LocalDate,
172+
This operator is used to compare numbers and dates. Available Java Types are **Timestamp, Date, Double, Long, LocalDate,
173173
ZonedDateTime, Instant, Integer**.
174174

175175
The following operators are available:

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@
7171
<artifactId>spring-data-jpa</artifactId>
7272
</dependency>
7373
<dependency>
74-
<groupId>jakarta.persistence</groupId>
75-
<artifactId>jakarta.persistence-api</artifactId>
74+
<groupId>javax.persistence</groupId>
75+
<artifactId>javax.persistence-api</artifactId>
7676
</dependency>
7777
<dependency>
7878
<groupId>org.hibernate</groupId>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.beyt.jdq.exception;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
5+
/**
6+
* Created by tdilber at 14-Seo-2024
7+
*/
8+
@Slf4j
9+
public class DynamicQueryIllegalArgumentException extends IllegalArgumentException {
10+
11+
public DynamicQueryIllegalArgumentException(String errorMessage) {
12+
super(errorMessage);
13+
log.error(errorMessage, this);
14+
}
15+
16+
public DynamicQueryIllegalArgumentException(String errorMessage, Throwable err) {
17+
super(errorMessage, err);
18+
log.error(errorMessage, err);
19+
}
20+
}

src/main/java/com/beyt/jdq/query/DynamicQueryManager.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.beyt.jdq.dto.Criteria;
77
import com.beyt.jdq.dto.DynamicQuery;
88
import com.beyt.jdq.dto.enums.CriteriaOperator;
9+
import com.beyt.jdq.exception.DynamicQueryIllegalArgumentException;
910
import com.beyt.jdq.query.rule.specification.*;
1011
import com.beyt.jdq.repository.DynamicSpecificationRepositoryImpl;
1112
import com.beyt.jdq.util.ApplicationContextUtil;
@@ -33,6 +34,7 @@
3334
import jakarta.persistence.criteria.*;
3435
import java.lang.reflect.Field;
3536
import java.lang.reflect.Method;
37+
import java.lang.reflect.RecordComponent;
3638
import java.util.*;
3739
import java.util.stream.Collectors;
3840
import java.util.stream.Stream;
@@ -171,6 +173,9 @@ private static <ResultType> void extractIfJdqModel(DynamicQuery dynamicQuery, Cl
171173
List<Pair<String, String>> select = new ArrayList<>();
172174
for (Field declaredField : resultTypeClass.getDeclaredFields()) {
173175
if (declaredField.isAnnotationPresent(JdqIgnoreField.class)) {
176+
if (resultTypeClass.isRecord()) {
177+
throw new DynamicQueryIllegalArgumentException("Record class can not have @JdqIgnoreField annotation");
178+
}
174179
continue;
175180
}
176181

@@ -307,27 +312,38 @@ protected static long executeCountQuery(TypedQuery<Long> query) {
307312

308313
protected static <ResultType> Iterable<ResultType> convertResultToResultTypeList(List<Pair<String, String>> querySelects, Class<ResultType> resultTypeClass, Iterable<Tuple> entityListBySelectableFilter, boolean isPage) {
309314
Map<Integer, Method> setterMethods = new HashMap<>();
310-
for (int i = 0; i < querySelects.size(); i++) {
311-
String select = querySelects.get(i).getSecond();
315+
if (!resultTypeClass.isRecord()) {
316+
for (int i = 0; i < querySelects.size(); i++) {
317+
String select = querySelects.get(i).getSecond();
312318

313-
Optional<Method> methodOptional = Arrays.stream(resultTypeClass.getMethods())
314-
.filter(c -> c.getName().equalsIgnoreCase("set" + select)
315-
&& c.getParameterCount() == 1).findFirst();
319+
Optional<Method> methodOptional = Arrays.stream(resultTypeClass.getMethods())
320+
.filter(c -> c.getName().equalsIgnoreCase("set" + select)
321+
&& c.getParameterCount() == 1).findFirst();
316322

317-
if (methodOptional.isPresent()) {
318-
setterMethods.put(i, methodOptional.get());
323+
if (methodOptional.isPresent()) {
324+
setterMethods.put(i, methodOptional.get());
325+
}
319326
}
320327
}
321328
Stream<Tuple> stream = isPage ? ((Page<Tuple>) entityListBySelectableFilter).stream() : ((List<Tuple>) entityListBySelectableFilter).stream();
322329

323330
List<ResultType> resultTypeList = stream.map(t -> {
324331
try {
325-
ResultType resultObj = resultTypeClass.getConstructor().newInstance();
326-
327-
for (Map.Entry<Integer, Method> entry : setterMethods.entrySet()) {
328-
entry.getValue().invoke(resultObj, t.get(entry.getKey()));
332+
if (resultTypeClass.isRecord()) {
333+
Object[] args = new Object[querySelects.size()];
334+
for (int i = 0; i < querySelects.size(); i++) {
335+
args[i] = t.get(i);
336+
}
337+
return resultTypeClass.getDeclaredConstructor(Arrays.stream(resultTypeClass.getRecordComponents())
338+
.map(RecordComponent::getType)
339+
.toArray(Class[]::new)).newInstance(args);
340+
} else {
341+
ResultType resultObj = resultTypeClass.getConstructor().newInstance();
342+
for (Map.Entry<Integer, Method> entry : setterMethods.entrySet()) {
343+
entry.getValue().invoke(resultObj, t.get(entry.getKey()));
344+
}
345+
return resultObj;
329346
}
330-
return resultObj;
331347
} catch (Exception e) {
332348
return null;
333349
}

src/main/java/com/beyt/jdq/util/ApplicationContextUtil.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,20 @@
1010

1111
public class ApplicationContextUtil implements ApplicationContextAware {
1212
private static ApplicationContext applicationContext;
13-
private static IEntityManagerProvider entityManagerProvider;
14-
private static IDeserializer deserializer;
15-
1613
@Override
1714
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
1815
ApplicationContextUtil.applicationContext = applicationContext;
19-
ApplicationContextUtil.entityManagerProvider = applicationContext.getBean(IEntityManagerProvider.class);
20-
ApplicationContextUtil.deserializer = applicationContext.getBean(IDeserializer.class);
2116
}
2217

2318
public static ApplicationContext getApplicationContext() {
2419
return applicationContext;
2520
}
2621

2722
public static EntityManager getEntityManager(){
28-
return entityManagerProvider.provide();
23+
return applicationContext.getBean(IEntityManagerProvider.class).provide();
2924
}
3025

3126
public static IDeserializer getDeserializer() {
32-
return deserializer;
27+
return applicationContext.getBean(IDeserializer.class);
3328
}
3429
}

src/main/java/com/beyt/jdq/util/field/FieldUtil.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Date;
1010
import java.util.HashMap;
1111
import java.util.Map;
12+
import java.sql.Timestamp;
1213

1314
/**
1415
* Created by tdilber at 11/17/2020
@@ -25,6 +26,7 @@ private FieldUtil() {
2526
fieldHelperMap.put(String.class, new StringFieldHelper());
2627
fieldHelperMap.put(Boolean.class, new BooleanFieldHelper());
2728
fieldHelperMap.put(Date.class, new DateFieldHelper());
29+
fieldHelperMap.put(Timestamp.class, new TimestampFieldHelper());
2830
fieldHelperMap.put(Double.class, new DoubleFieldHelper());
2931
fieldHelperMap.put(Long.class, new LongFieldHelper());
3032
fieldHelperMap.put(LocalDate.class, new LocalDateFieldHelper());
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.beyt.jdq.util.field.helper;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
5+
import java.text.DateFormat;
6+
import java.text.ParseException;
7+
import java.text.SimpleDateFormat;
8+
import java.sql.Timestamp;
9+
10+
/**
11+
* Created by tdilber at 11/17/2020
12+
*/
13+
@Slf4j
14+
public class TimestampFieldHelper implements IFieldHelper<Timestamp> {
15+
@Override
16+
public Timestamp fillRandom() {
17+
return new Timestamp(System.currentTimeMillis() + random.nextInt(1000000000));
18+
}
19+
20+
@Override
21+
public Timestamp fillValue(String value) {
22+
DateFormat dateFormat = new SimpleDateFormat();
23+
try {
24+
return new Timestamp(dateFormat.parse(value).getTime());
25+
} catch (ParseException e) {
26+
throw new IllegalStateException(e.getMessage(), e);
27+
}
28+
}
29+
30+
@Override
31+
public String createGeneratorCode(String value) {
32+
return "new Timestamp(" + fillValue(value).getTime() + "L)";
33+
}
34+
}

src/test/java/com/beyt/jdq/BaseTestInstance.java

Lines changed: 157 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@
22

33
import com.beyt.jdq.testenv.entity.Customer;
44
import com.beyt.jdq.testenv.entity.User;
5-
import com.beyt.jdq.testenv.repository.CustomerRepository;
6-
import com.beyt.jdq.testenv.repository.UserRepository;
5+
import com.beyt.jdq.testenv.entity.authorization.*;
6+
import com.beyt.jdq.testenv.entity.school.Address;
7+
import com.beyt.jdq.testenv.entity.school.Course;
8+
import com.beyt.jdq.testenv.entity.school.Department;
9+
import com.beyt.jdq.testenv.entity.school.Student;
10+
import com.beyt.jdq.testenv.repository.*;
11+
import org.junit.jupiter.api.BeforeAll;
712
import org.springframework.beans.factory.annotation.Autowired;
813

914
import jakarta.persistence.EntityManager;
1015
import java.util.Calendar;
16+
import java.sql.Timestamp;
17+
import java.util.List;
18+
import java.util.Set;
1119

1220
public abstract class BaseTestInstance {
1321

@@ -17,6 +25,31 @@ public abstract class BaseTestInstance {
1725
@Autowired
1826
protected UserRepository userRepository;
1927

28+
@Autowired
29+
protected AddressRepository addressRepository;
30+
31+
@Autowired
32+
protected RoleRepository roleRepository;
33+
34+
@Autowired
35+
protected DepartmentRepository departmentRepository;
36+
37+
@Autowired
38+
protected CourseRepository courseRepository;
39+
40+
@Autowired
41+
protected StudentRepository studentRepository;
42+
43+
@Autowired
44+
protected AuthorizationRepository authorizationRepository;
45+
46+
@Autowired
47+
protected RoleAuthorizationRepository roleAuthorizationRepository;
48+
49+
@Autowired
50+
protected AdminUserRepository adminUserRepository;
51+
52+
2053
@Autowired
2154
protected EntityManager entityManager;
2255

@@ -39,6 +72,77 @@ public abstract class BaseTestInstance {
3972
public final Customer customer8;
4073
public static final Calendar INSTANCE = Calendar.getInstance();
4174

75+
protected Address address1 = new Address(1L, "123 Main St", "New York", "NY", "10001");
76+
protected Address address2 = new Address(2L, "456 Park Ave", "Chicago", "IL", "60605");
77+
protected Address address3 = new Address(3L, "789 Broadway", "Los Angeles", "CA", "90001");
78+
protected Address address4 = new Address(4L, "321 Market St", "San Francisco", "CA", "94105");
79+
protected Address address5 = new Address(5L, "654 Elm St", "Dallas", "TX", "75001");
80+
protected Address address6 = new Address(6L, "987 Oak St", "Houston", "TX", "77002");
81+
protected Address address7 = new Address(7L, "345 Pine St", "Philadelphia", "PA", "19019");
82+
protected Address address8 = new Address(8L, "678 Maple St", "Phoenix", "AZ", "85001");
83+
protected Address address9 = new Address(9L, "102 Beach St", "Miami", "FL", "33101");
84+
protected Address address10 = new Address(10L, "567 Hill St", "Atlanta", "GA", "30301");
85+
86+
87+
protected Department department1 = new Department(1L, "Computer Science");
88+
protected Department department2 = new Department(2L, "Mathematics");
89+
protected Department department3 = new Department(3L, "Physics");
90+
protected Department department4 = new Department(4L, "Chemistry");
91+
protected Department department5 = new Department(5L, "Biology");
92+
protected Department department6 = new Department(6L, "English Literature");
93+
protected Department department7 = new Department(7L, "History");
94+
protected Department department8 = new Department(8L, "Geography");
95+
protected Department department9 = new Department(9L, "Political Science");
96+
protected Department department10 = new Department(10L, "Economics");
97+
98+
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.");
99+
protected Course course2 = new Course(2L, "Calculus I", Timestamp.valueOf("2017-06-18 00:00:00"), 60, true, "Introduction to fundamental concepts of calculus.");
100+
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.");
101+
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.");
102+
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.");
103+
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.");
104+
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.");
105+
protected Course course8 = new Course(8L, "Biology I", Timestamp.valueOf("2015-06-18 00:00:00"), 20, true, "Introduction to cellular biology and genetics.");
106+
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.");
107+
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.");
108+
109+
protected Student student1 = new Student(1L, "John Doe", address1, department1, List.of(course1, course2));
110+
protected Student student2 = new Student(2L, "Jane Smith", address2, department2, List.of(course2, course4));
111+
protected Student student3 = new Student(3L, "Robert Johnson", address3, department3, List.of(course3));
112+
protected Student student4 = new Student(4L, "Emily Davis", address4, department4, List.of(course4));
113+
protected Student student5 = new Student(5L, "Michael Miller", address5, department5, List.of(course5));
114+
protected Student student6 = new Student(6L, "Sarah Wilson", address6, department6, List.of(course6));
115+
protected Student student7 = new Student(7L, "David Moore", address7, department7, List.of(course7));
116+
protected Student student8 = new Student(8L, "Jessica Taylor", address8, department8, List.of(course8));
117+
protected Student student9 = new Student(9L, "Daniel Anderson", address9, department9, List.of(course9));
118+
protected Student student10 = new Student(10L, "Jennifer Thomas", address10, department10, List.of(course10));
119+
protected Student student11 = new Student(11L, "Talha Dilber", null, null, List.of());
120+
121+
protected Authorization authorization1 = new Authorization(1L, "auth1", "/url1", "icon1");
122+
protected Authorization authorization2 = new Authorization(2L, "auth2", "/url2", "icon2");
123+
protected Authorization authorization3 = new Authorization(3L, "auth3", "/url3", "icon3");
124+
protected Authorization authorization4 = new Authorization(4L, "auth4", "/url4", "icon4");
125+
protected Authorization authorization5 = new Authorization(5L, "auth5", "/url5", "icon5");
126+
127+
protected Role role1 = new Role(1L, "role1", "description1");
128+
protected Role role2 = new Role(2L, "role2", "description2");
129+
protected Role role3 = new Role(3L, "role3", "description3");
130+
protected Role role4 = new Role(4L, "role4", "description4");
131+
protected Role role5 = new Role(5L, "role5", "description5");
132+
133+
protected RoleAuthorization roleAuthorization1 = new RoleAuthorization(1L, role1, authorization1);
134+
protected RoleAuthorization roleAuthorization2 = new RoleAuthorization(2L, role2, authorization2);
135+
protected RoleAuthorization roleAuthorization3 = new RoleAuthorization(3L, role3, authorization3);
136+
protected RoleAuthorization roleAuthorization4 = new RoleAuthorization(4L, role4, authorization4);
137+
protected RoleAuthorization roleAuthorization5 = new RoleAuthorization(5L, role5, authorization5);
138+
139+
140+
protected AdminUser adminUser1 = new AdminUser(1L, "admin1", "password1", List.of(role1));
141+
protected AdminUser adminUser2 = new AdminUser(2L, "admin2", "password2", List.of(role2));
142+
protected AdminUser adminUser3 = new AdminUser(3L, "admin3", "password3", List.of(role3));
143+
protected AdminUser adminUser4 = new AdminUser(4L, "admin4", "password4", List.of(role4));
144+
protected AdminUser adminUser5 = new AdminUser(5L, "admin5", "password5", List.of(role5));
145+
42146
public BaseTestInstance() {
43147
user1 = new User(null, "Name 1", "Surname 1", 35, INSTANCE.toInstant(), User.Status.PASSIVE, User.Type.USER);
44148
customer1 = new Customer(null, "Customer 1", 20, INSTANCE.toInstant(), user1);
@@ -65,4 +169,55 @@ public BaseTestInstance() {
65169
customer8 = new Customer(null, null, 27, INSTANCE.toInstant(), user8);
66170

67171
}
172+
173+
174+
@BeforeAll
175+
public void init() {
176+
if (userRepository.count() != 0) {
177+
return;
178+
}
179+
userRepository.save(user1);
180+
userRepository.save(user2);
181+
userRepository.save(user3);
182+
userRepository.save(user4);
183+
userRepository.save(user5);
184+
userRepository.save(user6);
185+
userRepository.save(user7);
186+
userRepository.save(user8);
187+
188+
if (customerRepository.count() != 0) {
189+
return;
190+
}
191+
customerRepository.save(customer1);
192+
customerRepository.save(customer2);
193+
customerRepository.save(customer3);
194+
customerRepository.save(customer4);
195+
customerRepository.save(customer5);
196+
customerRepository.save(customer6);
197+
customerRepository.save(customer7);
198+
customerRepository.save(customer8);
199+
200+
if (addressRepository.count() != 0) {
201+
return;
202+
}
203+
addressRepository.saveAllAndFlush(List.of(address1, address2, address3, address4, address5, address6, address7, address8, address9, address10));
204+
205+
departmentRepository.saveAllAndFlush(List.of(department1, department2, department3, department4, department5, department6, department7, department8, department9, department10));
206+
207+
courseRepository.saveAllAndFlush(List.of(course1, course2, course3, course4, course5, course6, course7, course8, course9, course10));
208+
209+
studentRepository.saveAllAndFlush(List.of(student1, student2, student3, student4, student5, student6, student7, student8, student9, student10, student11));
210+
211+
if (authorizationRepository.count() != 0) {
212+
return;
213+
}
214+
authorizationRepository.saveAllAndFlush(List.of(authorization1, authorization2, authorization3, authorization4, authorization5));
215+
216+
roleRepository.saveAllAndFlush(List.of(role1, role2, role3, role4, role5));
217+
218+
roleAuthorizationRepository.saveAllAndFlush(List.of(roleAuthorization1, roleAuthorization2, roleAuthorization3, roleAuthorization4, roleAuthorization5));
219+
220+
adminUserRepository.saveAllAndFlush(List.of(adminUser1, adminUser2, adminUser3, adminUser4, adminUser5));
221+
}
222+
68223
}

0 commit comments

Comments
 (0)