Is there a way to return the aggregate count in a Dynamic Projection with Specification in JPA?

27 views Asked by At

I'm using Spring Data with a repository:

public interface MyEntityClassStatisticRepository extends Repository<MyEntityClass, Integer>, JpaSpecificationExecutor<MyEntityClass> {

   <T> List<T> findBy(Specification<MyEntityClass> spec, Class<T> tClass);
}

In this repository, I have a method that queries within a Specification. The Specification is built like this:

     Specification<MyEntityClass> specification = (root, query, criteriaBuilder) -> {
            Join<MyEntityClass, StateEntityClass> state = root.join("lastState");
            Join<MyEntityClass, SubstateEntityClass> subState = root.join("lastSubstate");
            query.multiselect(state.get("name"), substate.get("name"),criteriaBuilder.count(root));
            query.groupBy(state.get("name"), substate.get("name"));
            return criteriaBuilder.greaterThan(root.get("id"),0);
        }; 

I have a Projection that I created for this purpose with three attributes: lastStateName, lastSubstateName, and totalCount.

When I call the method findBy, it throws the following Exception, and I don't know how to solve it:

org.springframework.data.mapping.PropertyReferenceException: No property totalOcurrences found for type StateEntityClass!
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:382) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:358) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:311) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324) ~[?:1.8.0_301]
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:293) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:276) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:175) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:152) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:59) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:232) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:106) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:226) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:126) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:619) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:606) ~[spring-data-commons-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:371) ~[spring-tx-5.3.0.jar:5.3.0]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:134) ~[spring-tx-5.3.0.jar:5.3.0]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.0.jar:5.3.0]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149) ~[spring-data-jpa-2.2.13.RELEASE.jar:2.2.13.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.0.jar:5.3.0]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.0.jar:5.3.0]
    at com.sun.proxy.$Proxy161.findBy(Unknown Source) ~[?:?]
.....

I'm attempting to modify the Specification and utilize a @Query annotation instead for querying. However, I still want to retain the usage of Specification since it's utilized in other services and provides significant functionality.

0

There are 0 answers