Hi,

I am having a particular issue that doesn't want to go away.
I have created a Custom Repository that handles dynamic search in my own custom way. See the code below

Code:
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable, Q extends BaseEntityQueryCriteria>
        extends JpaRepository<T, ID>, Serializable {

    List<T> criteriaSearch(
            Q entityCriteria);
}
The implementation is adapted from a custom search I built in the Jpa 1.x days. I am still comfortable with it.
Code:
class BaseRepositoryImpl<T, ID extends Serializable, Q extends BaseEntityQueryCriteria>
        extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID, Q> {

    @Resource
    private EntityManager entityManager;
    /**
     * EMPTY_STRING
     */
    //private final static String EMPTY_STRING = " ";
    /**
     * PRIMARY_ENTITY
     */
    private final String PRIMARY_ENTITY = "{PRIMARY_ENTITY}";

//    public BaseRepositoryImpl() {
//    }

    /**
     * constructor
     */
    public BaseRepositoryImpl(Class<T> entityClass, EntityManager _entityManager) {
        super(entityClass, _entityManager);
        //set this entitymanager
        this.entityManager = _entityManager;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> criteriaSearch(
            Q entityCriteria) {

        String queryString = buildQuery(entityCriteria);
        Query query = entityManager.createQuery(queryString);
        setQueryParameter(query, entityCriteria.getParameters());
        return query.getResultList();
    }

    /**
     *
     *
     */
    private String buildQuery(BaseQueryCriteria baseQueryBuilder) {
        String entityName = baseQueryBuilder.getEntityName();
        String sqlScript = baseQueryBuilder.getSqlString();
        sqlScript = sqlScript.replace(PRIMARY_ENTITY, entityName);
        baseQueryBuilder = null;
        return sqlScript;
    }

    /**
     * sets the various parameters on the JPQL using the map that is passed in.
     *
     * @param Query - the query object to be set
     * @Map - parameters
     */
    private void setQueryParameter(Query query, Map<String, Object> parameters) {
        Set<String> keySet = parameters.keySet();
        if (keySet.size() > 0) {
            for (String placeHolder : keySet) {
                Object object = parameters.get(placeHolder);
                if (object instanceof String) {
                    object = ((String) object).toLowerCase();
                }
                query.setParameter(placeHolder, object);
            }
        }
    }
}
the factory bean is
Code:
public class BaseRepositoryFactoryBean<R extends JpaRepository<T, ID>, T, ID extends Serializable>
        extends JpaRepositoryFactoryBean<R, T, ID> {

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {

        return new MyRepositoryFactory(entityManager);
    }

    /**
     *
     * @param <T>
     * @param <I>
     */
    private static class MyRepositoryFactory<T, ID extends Serializable, Q extends BaseEntityQueryCriteria>
            extends JpaRepositoryFactory {

        /**
         *
         */
        private EntityManager entityManager;

        /**
         * constructor
         *
         * @param entityManager
         */
        public MyRepositoryFactory(EntityManager entityManager) {
            super(entityManager);

            this.entityManager = entityManager;
        }

        @Override
        protected Object getTargetRepository(RepositoryMetadata metadata) {
            return new BaseRepositoryImpl<T, ID, Q>((Class<T>) metadata.getDomainType(), entityManager);
        }

        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
            // The RepositoryMetadata can be safely ignored, it is used by the JpaRepositoryFactory
            //to check for QueryDslJpaRepository's which is out of scope.
            return BaseRepositoryImpl.class;
        }
    }
}
The problem now is that I have a repository interface that extends BaseRepository like this
Code:
@Repository
public interface StoreRepo extends BaseRepository<Store, Integer, StoreQueryCriteria> {
}
However, a call to storeRepo.criteriaSearch(new StoreQueryCriteria())
throws the exception

Code:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'storeRepo': FactoryBean threw exception on object creation; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property criteria found for type com.okmich.storeruns.common.entity.Store
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1441)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:305)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at StoreTest.main(StoreTest.java:22)
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property criteria found for type com.okmich.storeruns.common.entity.Store
	at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:74)
	at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:326)
	at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:352)
	at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:306)
	at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
	at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:244)
	at org.springframework.data.repository.query.parser.Part.<init>(Part.java:73)
	at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:180)
	at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:260)
	at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:240)
	at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:68)
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:57)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:90)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:68)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:280)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:148)
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:125)
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:41)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
	... 10 more

I know this has to do with the Query Derivation strategy. However, for my case I want to override it or better still have a fine grain control so as to prevent derivation of query for this custom method.

How do I do this? I have googled for a clue but no way so far.


Regards.