Spring data JPA Hibernate mapping dynamic query to List(Map) instead List POJO
Hi every one,
This way i'll show you how to mapping dynamic query on hibernate to list<map> for dynamic result instead create new pojo/ dto class✋
- You can be use only hibernate or spring data jpa(including hibernate on compile dependencies) 👌
Importing framework
Build tool: Grandle, spring boot 3.x.x
a. Dependencies:
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
b. Compile dependencies on spring data jpa:
c. Version:
id 'org.springframework.boot' version '3.0.2'
Implementing
1. Create a generic repository custom
public interface GenericRepoCustom {
long counting(String sql);
List findStrategy(String sql, Class clazz);
}
long counting(String sql);
List findStrategy(String sql, Class clazz);
}
2. Autowire GenericRepoCustom on service
3. Call it and passing class type
List<Map> orders = genericRepo.findStrategy(strSQL, Map.class);
strSQL: work well when get one or get list
4. Create function mapping if clazz is Map.class
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.TupleElement;
import lombok.extern.slf4j.Slf4j;
import mobileskips.persistence.repo.custom.GenericRepoCustom;
import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.TupleElement;
import lombok.extern.slf4j.Slf4j;
import mobileskips.persistence.repo.custom.GenericRepoCustom;
import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class GenericRepoImpl implements GenericRepoCustom {
@PersistenceContext
private EntityManager em;
@Override
public long counting(String sql) {
return Long.parseLong(em.createNativeQuery(sql).getSingleResult().toString());
}
@Override
public List<?> findStrategy(String sql, Class clazz) {
if (clazz == Map.class) {
List<Tuple> resultListTuple = em.createNativeQuery(sql, Tuple.class).getResultList();
return toMap(resultListTuple);
}
return em.createNativeQuery(sql, clazz).getResultList();
}
List<Map> toMap(List<Tuple> resultList) {
List<Map> result = new ArrayList<>();
List<TupleElement<?>> elements = CollectionUtils.isEmpty(resultList) ? null : resultList.get(0).getElements();
for (Tuple tuple : resultList) {
if (elements == null) {
continue;
}
Map fields = new HashMap();
for (TupleElement element : elements) {
fields.put(element.getAlias(), tuple.get(element));
}
result.add(fields);
}
return result;
}
}
public class GenericRepoImpl implements GenericRepoCustom {
@PersistenceContext
private EntityManager em;
@Override
public long counting(String sql) {
return Long.parseLong(em.createNativeQuery(sql).getSingleResult().toString());
}
@Override
public List<?> findStrategy(String sql, Class clazz) {
if (clazz == Map.class) {
List<Tuple> resultListTuple = em.createNativeQuery(sql, Tuple.class).getResultList();
return toMap(resultListTuple);
}
return em.createNativeQuery(sql, clazz).getResultList();
}
List<Map> toMap(List<Tuple> resultList) {
List<Map> result = new ArrayList<>();
List<TupleElement<?>> elements = CollectionUtils.isEmpty(resultList) ? null : resultList.get(0).getElements();
for (Tuple tuple : resultList) {
if (elements == null) {
continue;
}
Map fields = new HashMap();
for (TupleElement element : elements) {
fields.put(element.getAlias(), tuple.get(element));
}
result.add(fields);
}
return result;
}
}
- findStrategy(): you can custommize for getSingleResult or getResultList. Current i using for both and return List<?> 👅
Comments
Post a Comment