@ -17,6 +17,8 @@ package org.springframework.data.mongodb.repository.query;
import java.util.List ;
import java.util.List ;
import org.springframework.core.convert.ConversionService ;
import org.springframework.core.convert.support.DefaultConversionService ;
import org.springframework.data.domain.PageImpl ;
import org.springframework.data.domain.PageImpl ;
import org.springframework.data.domain.Pageable ;
import org.springframework.data.domain.Pageable ;
import org.springframework.data.mongodb.core.MongoOperations ;
import org.springframework.data.mongodb.core.MongoOperations ;
@ -39,6 +41,8 @@ import org.springframework.util.Assert;
* /
* /
public abstract class AbstractMongoQuery implements RepositoryQuery {
public abstract class AbstractMongoQuery implements RepositoryQuery {
private static final ConversionService CONVERSION_SERVICE = new DefaultConversionService ( ) ;
private final MongoQueryMethod method ;
private final MongoQueryMethod method ;
private final MongoOperations operations ;
private final MongoOperations operations ;
@ -86,9 +90,33 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
return new CollectionExecution ( accessor . getPageable ( ) ) . execute ( query ) ;
return new CollectionExecution ( accessor . getPageable ( ) ) . execute ( query ) ;
} else if ( method . isPageQuery ( ) ) {
} else if ( method . isPageQuery ( ) ) {
return new PagedExecution ( accessor . getPageable ( ) ) . execute ( query ) ;
return new PagedExecution ( accessor . getPageable ( ) ) . execute ( query ) ;
} else {
return new SingleEntityExecution ( ) . execute ( query ) ;
}
}
Object result = new SingleEntityExecution ( isCountQuery ( ) ) . execute ( query ) ;
if ( result = = null ) {
return result ;
}
Class < ? > expectedReturnType = method . getReturnType ( ) . getType ( ) ;
if ( expectedReturnType . isAssignableFrom ( result . getClass ( ) ) ) {
return result ;
}
return CONVERSION_SERVICE . convert ( result , expectedReturnType ) ;
}
/ * *
* Creates a { @link Query } instance using the given { @link ConvertingParameterAccessor } . Will delegate to
* { @link # createQuery ( ConvertingParameterAccessor ) } by default but allows customization of the count query to be
* triggered .
*
* @param accessor must not be { @literal null } .
* @return
* /
protected Query createCountQuery ( ConvertingParameterAccessor accessor ) {
return createQuery ( accessor ) ;
}
}
/ * *
/ * *
@ -100,16 +128,11 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
protected abstract Query createQuery ( ConvertingParameterAccessor accessor ) ;
protected abstract Query createQuery ( ConvertingParameterAccessor accessor ) ;
/ * *
/ * *
* Creates a { @link Query } instance using the given { @link ConvertingParameterAccessor } . Will delegate to
* Returns whether the query should get a count projection applied .
* { @link # createQuery ( ConvertingParameterAccessor ) } by default but allows customization of the count query to be
* triggered .
*
*
* @param accessor must not be { @literal null } .
* @return
* @return
* /
* /
protected Query createCountQuery ( ConvertingParameterAccessor accessor ) {
protected abstract boolean isCountQuery ( ) ;
return createQuery ( accessor ) ;
}
private abstract class Execution {
private abstract class Execution {
@ -191,6 +214,12 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
* /
* /
class SingleEntityExecution extends Execution {
class SingleEntityExecution extends Execution {
private final boolean countProjection ;
private SingleEntityExecution ( boolean countProjection ) {
this . countProjection = countProjection ;
}
/ *
/ *
* ( non - Javadoc )
* ( non - Javadoc )
* @see org . springframework . data . mongodb . repository . AbstractMongoQuery . Execution # execute ( org . springframework . data . mongodb . core . core . query . Query )
* @see org . springframework . data . mongodb . repository . AbstractMongoQuery . Execution # execute ( org . springframework . data . mongodb . core . core . query . Query )
@ -199,7 +228,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
Object execute ( Query query ) {
Object execute ( Query query ) {
MongoEntityMetadata < ? > metadata = method . getEntityInformation ( ) ;
MongoEntityMetadata < ? > metadata = method . getEntityInformation ( ) ;
return operations . findOne ( query , metadata . getJavaType ( ) ) ;
return countProjection ? operations . count ( query , metadata . getJavaType ( ) ) : operations . findOne ( query ,
metadata . getJavaType ( ) ) ;
}
}
}
}