Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ You can find the sample code from: https://github.com/tdilber/spring-jpa-dynamic
<dependency>
<groupId>io.github.tdilber</groupId>
<artifactId>spring-boot-starter-jpa-dynamic-query</artifactId>
<version>0.1.0</version>
<version>0.2.0</version>
</dependency>
```

Expand All @@ -108,7 +108,7 @@ You can find the sample code from: https://github.com/tdilber/spring-jpa-dynamic
<dependency>
<groupId>io.github.tdilber</groupId>
<artifactId>spring-jpa-dynamic-query</artifactId>
<version>0.4.0</version>
<version>0.5.0</version>
</dependency>
```

Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<groupId>io.github.tdilber</groupId>
<artifactId>spring-boot-starter-jpa-dynamic-query</artifactId>
<version>0.1.0</version>
<version>0.2.0</version>
<packaging>jar</packaging>
<name>Spring Jpa Dynamic Query</name>
<description>Spring Jpa Dynamic Query (JDQ) Project</description>
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
40 changes: 28 additions & 12 deletions src/main/java/com/beyt/jdq/query/DynamicQueryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -171,6 +173,9 @@ private static <ResultType> void extractIfJdqModel(DynamicQuery dynamicQuery, Cl
List<Pair<String, String>> 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;
}

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

protected static <ResultType> Iterable<ResultType> convertResultToResultTypeList(List<Pair<String, String>> querySelects, Class<ResultType> resultTypeClass, Iterable<Tuple> entityListBySelectableFilter, boolean isPage) {
Map<Integer, Method> 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<Method> methodOptional = Arrays.stream(resultTypeClass.getMethods())
.filter(c -> c.getName().equalsIgnoreCase("set" + select)
&& c.getParameterCount() == 1).findFirst();
Optional<Method> 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<Tuple> stream = isPage ? ((Page<Tuple>) entityListBySelectableFilter).stream() : ((List<Tuple>) entityListBySelectableFilter).stream();

List<ResultType> resultTypeList = stream.map(t -> {
try {
ResultType resultObj = resultTypeClass.getConstructor().newInstance();

for (Map.Entry<Integer, Method> 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<Integer, Method> entry : setterMethods.entrySet()) {
entry.getValue().invoke(resultObj, t.get(entry.getKey()));
}
return resultObj;
}
return resultObj;
} catch (Exception e) {
return null;
}
Expand Down
9 changes: 2 additions & 7 deletions src/main/java/com/beyt/jdq/util/ApplicationContextUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,20 @@

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() {
return applicationContext;
}

public static EntityManager getEntityManager(){
return entityManagerProvider.provide();
return applicationContext.getBean(IEntityManagerProvider.class).provide();
}

public static IDeserializer getDeserializer() {
return deserializer;
return applicationContext.getBean(IDeserializer.class);
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/beyt/jdq/util/field/FieldUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Timestamp> {
@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)";
}
}
Loading