Work on perf enhancements to JPA

This commit is contained in:
James Agnew 2017-03-30 19:58:32 +08:00
parent ce73e89715
commit efaa7a74cb
7 changed files with 86 additions and 70 deletions

View File

@ -36,6 +36,8 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class DateRangeParam implements IQueryParameterAnd<DateParam> { public class DateRangeParam implements IQueryParameterAnd<DateParam> {
private static final long serialVersionUID = 1L;
private DateParam myLowerBound; private DateParam myLowerBound;
private DateParam myUpperBound; private DateParam myUpperBound;
@ -202,6 +204,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
break; break;
case LESSTHAN: case LESSTHAN:
case LESSTHAN_OR_EQUALS: case LESSTHAN_OR_EQUALS:
default:
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getPrefix()); throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getPrefix());
} }
} }
@ -229,6 +232,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
break; break;
case GREATERTHAN_OR_EQUALS: case GREATERTHAN_OR_EQUALS:
case GREATERTHAN: case GREATERTHAN:
default:
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getPrefix()); throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getPrefix());
} }
} }

View File

@ -84,10 +84,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeChildResourceDefinition; import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao; import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.BaseHasResource; import ca.uhn.fhir.jpa.entity.BaseHasResource;
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam; import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
import ca.uhn.fhir.jpa.entity.BaseTag; import ca.uhn.fhir.jpa.entity.BaseTag;
@ -110,6 +107,7 @@ import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.entity.TagDefinition; import ca.uhn.fhir.jpa.entity.TagDefinition;
import ca.uhn.fhir.jpa.entity.TagTypeEnum; import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider; import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.util.DeleteConflict; import ca.uhn.fhir.jpa.util.DeleteConflict;
import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
@ -164,7 +162,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
public static final String OO_SEVERITY_WARN = "warning"; public static final String OO_SEVERITY_WARN = "warning";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirDao.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirDao.class);
private static final Map<FhirVersionEnum, FhirContext> ourRetrievalContexts = new HashMap<FhirVersionEnum, FhirContext>(); private static final Map<FhirVersionEnum, FhirContext> ourRetrievalContexts = new HashMap<FhirVersionEnum, FhirContext>();
private static final String PROCESSING_SUB_REQUEST = "BaseHapiFhirDao.processingSubRequest"; private static final String PROCESSING_SUB_REQUEST = "BaseHapiFhirDao.processingSubRequest";
/** /**
* These are parameters which are supported by {@link BaseHapiFhirResourceDao#searchForIds(Map)} * These are parameters which are supported by {@link BaseHapiFhirResourceDao#searchForIds(Map)}
@ -192,17 +189,17 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
RESOURCE_META_PARAMS = Collections.unmodifiableMap(resourceMetaParams); RESOURCE_META_PARAMS = Collections.unmodifiableMap(resourceMetaParams);
RESOURCE_META_AND_PARAMS = Collections.unmodifiableMap(resourceMetaAndParams); RESOURCE_META_AND_PARAMS = Collections.unmodifiableMap(resourceMetaAndParams);
} }
@Autowired(required = true) @Autowired(required = true)
private DaoConfig myConfig; private DaoConfig myConfig;
private FhirContext myContext; private FhirContext myContext;
@PersistenceContext(type = PersistenceContextType.TRANSACTION) @PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager; protected EntityManager myEntityManager;
@Autowired @Autowired
protected IForcedIdDao myForcedIdDao; protected IForcedIdDao myForcedIdDao;
@Autowired(required = false)
protected IFulltextSearchSvc myFulltextSearchSvc;
@Autowired @Autowired
private PlatformTransactionManager myPlatformTransactionManager; private PlatformTransactionManager myPlatformTransactionManager;
@ -212,6 +209,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
@Autowired @Autowired
private IResourceHistoryTableDao myResourceHistoryTableDao; private IResourceHistoryTableDao myResourceHistoryTableDao;
@Autowired()
protected IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> myResourceTypeToDao; private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> myResourceTypeToDao;
@Autowired @Autowired
@ -226,6 +226,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
@Autowired @Autowired
private ISearchResultDao mySearchResultDao; private ISearchResultDao mySearchResultDao;
@Autowired
protected ISearchParamRegistry mySerarchParamRegistry;
@Autowired()
protected IHapiTerminologySvc myTerminologySvc;
protected void clearRequestAsProcessingSubRequest(ServletRequestDetails theRequestDetails) { protected void clearRequestAsProcessingSubRequest(ServletRequestDetails theRequestDetails) {
if (theRequestDetails != null) { if (theRequestDetails != null) {
theRequestDetails.getUserData().remove(PROCESSING_SUB_REQUEST); theRequestDetails.getUserData().remove(PROCESSING_SUB_REQUEST);
@ -397,26 +403,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} }
protected boolean isLogicalReference(IIdType theId) {
Set<String> treatReferencesAsLogical = myConfig.getTreatReferencesAsLogical();
if (treatReferencesAsLogical != null) {
for (String nextLogicalRef : treatReferencesAsLogical) {
nextLogicalRef = trim(nextLogicalRef);
if (nextLogicalRef.charAt(nextLogicalRef.length() - 1) == '*') {
if (theId.getValue().startsWith(nextLogicalRef.substring(0, nextLogicalRef.length() - 1))) {
return true;
}
} else {
if (theId.getValue().equals(nextLogicalRef)) {
return true;
}
}
}
}
return false;
}
protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IBaseResource theResource) { protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource); return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource);
} }
@ -698,12 +684,40 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
theProvider.setSearchResultDao(mySearchResultDao); theProvider.setSearchResultDao(mySearchResultDao);
} }
protected boolean isLogicalReference(IIdType theId) {
Set<String> treatReferencesAsLogical = myConfig.getTreatReferencesAsLogical();
if (treatReferencesAsLogical != null) {
for (String nextLogicalRef : treatReferencesAsLogical) {
nextLogicalRef = trim(nextLogicalRef);
if (nextLogicalRef.charAt(nextLogicalRef.length() - 1) == '*') {
if (theId.getValue().startsWith(nextLogicalRef.substring(0, nextLogicalRef.length() - 1))) {
return true;
}
} else {
if (theId.getValue().equals(nextLogicalRef)) {
return true;
}
}
}
}
return false;
}
protected void markRequestAsProcessingSubRequest(ServletRequestDetails theRequestDetails) { protected void markRequestAsProcessingSubRequest(ServletRequestDetails theRequestDetails) {
if (theRequestDetails != null) { if (theRequestDetails != null) {
theRequestDetails.getUserData().put(PROCESSING_SUB_REQUEST, Boolean.TRUE); theRequestDetails.getUserData().put(PROCESSING_SUB_REQUEST, Boolean.TRUE);
} }
} }
@Override
public SearchBuilder newSearchBuilder() {
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myPlatformTransactionManager, myFulltextSearchSvc, mySearchResultDao, this, myResourceIndexedSearchParamUriDao,
myForcedIdDao,
myTerminologySvc, mySerarchParamRegistry);
return builder;
}
protected void notifyInterceptors(RestOperationTypeEnum theOperationType, ActionRequestDetails theRequestDetails) { protected void notifyInterceptors(RestOperationTypeEnum theOperationType, ActionRequestDetails theRequestDetails) {
if (theRequestDetails.getId() != null && theRequestDetails.getId().hasResourceType() && isNotBlank(theRequestDetails.getResourceType())) { if (theRequestDetails.getId() != null && theRequestDetails.getId().hasResourceType() && isNotBlank(theRequestDetails.getResourceType())) {
if (theRequestDetails.getId().getResourceType().equals(theRequestDetails.getResourceType()) == false) { if (theRequestDetails.getId().getResourceType().equals(theRequestDetails.getResourceType()) == false) {
@ -967,7 +981,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
* The entity being updated (Do not modify the entity! Undefined behaviour will occur!) * The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
* @param theTag * @param theTag
* The tag * The tag
* @return Returns <code>true</code> if the tag should be removed
*/ */
protected void postPersist(ResourceTable theEntity, T theResource) { protected void postPersist(ResourceTable theEntity, T theResource) {
// nothing // nothing
@ -1024,6 +1037,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
myPlatformTransactionManager = thePlatformTransactionManager; myPlatformTransactionManager = thePlatformTransactionManager;
} }
private void setUpdatedTime(Collection<? extends BaseResourceIndexedSearchParam> theParams, Date theUpdateTime) {
for (BaseResourceIndexedSearchParam nextSearchParam : theParams) {
nextSearchParam.setUpdated(theUpdateTime);
}
}
/** /**
* This method is called when an update to an existing resource detects that the resource supplied for update is missing a tag/profile/security label that the currently persisted resource holds. * This method is called when an update to an existing resource detects that the resource supplied for update is missing a tag/profile/security label that the currently persisted resource holds.
* <p> * <p>
@ -1483,12 +1502,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return theEntity; return theEntity;
} }
private void setUpdatedTime(Collection<? extends BaseResourceIndexedSearchParam> theParams, Date theUpdateTime) {
for (BaseResourceIndexedSearchParam nextSearchParam : theParams) {
nextSearchParam.setUpdated(theUpdateTime);
}
}
protected ResourceTable updateEntity(IBaseResource theResource, ResourceTable entity, Date theDeletedTimestampOrNull, Date theUpdateTime) { protected ResourceTable updateEntity(IBaseResource theResource, ResourceTable entity, Date theDeletedTimestampOrNull, Date theUpdateTime) {
return updateEntity(theResource, entity, theDeletedTimestampOrNull, true, true, theUpdateTime); return updateEntity(theResource, entity, theDeletedTimestampOrNull, true, true, theUpdateTime);
} }

View File

@ -78,8 +78,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
protected PlatformTransactionManager myPlatformTransactionManager; protected PlatformTransactionManager myPlatformTransactionManager;
@Autowired @Autowired
private IResourceHistoryTableDao myResourceHistoryTableDao; private IResourceHistoryTableDao myResourceHistoryTableDao;
@Autowired()
protected IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
private String myResourceName; private String myResourceName;
@Autowired @Autowired
protected IResourceTableDao myResourceTableDao; protected IResourceTableDao myResourceTableDao;
@ -89,10 +87,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Autowired() @Autowired()
protected ISearchResultDao mySearchResultDao; protected ISearchResultDao mySearchResultDao;
private String mySecondaryPrimaryKeyParamName; private String mySecondaryPrimaryKeyParamName;
@Autowired
private ISearchParamRegistry mySerarchParamRegistry;
@Autowired()
protected IHapiTerminologySvc myTerminologySvc;
@Override @Override
public void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) { public void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) {
@ -961,12 +955,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getContext(), getResourceName(), null); ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getContext(), getResourceName(), null);
notifyInterceptors(RestOperationTypeEnum.SEARCH_TYPE, requestDetails); notifyInterceptors(RestOperationTypeEnum.SEARCH_TYPE, requestDetails);
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myPlatformTransactionManager, mySearchDao, mySearchResultDao, this, myResourceIndexedSearchParamUriDao, myForcedIdDao, SearchBuilder builder = newSearchBuilder();
myTerminologySvc, mySerarchParamRegistry);
builder.setType(getResourceType(), getResourceName()); builder.setType(getResourceType(), getResourceName());
return builder.search(theParams); return builder.search(theParams);
} }
@Override @Override
public IBundleProvider search(String theParameterName, IQueryParameterType theValue) { public IBundleProvider search(String theParameterName, IQueryParameterType theValue) {
return search(Collections.singletonMap(theParameterName, theValue)); return search(Collections.singletonMap(theParameterName, theValue));
@ -990,8 +984,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
public Set<Long> searchForIdsWithAndOr(SearchParameterMap theParams) { public Set<Long> searchForIdsWithAndOr(SearchParameterMap theParams) {
theParams.setPersistResults(false); theParams.setPersistResults(false);
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myPlatformTransactionManager, mySearchDao, mySearchResultDao, this, myResourceIndexedSearchParamUriDao, myForcedIdDao, SearchBuilder builder = newSearchBuilder();
myTerminologySvc, mySerarchParamRegistry);
builder.setType(getResourceType(), getResourceName()); builder.setType(getResourceType(), getResourceName());
builder.search(theParams); builder.search(theParams);
return builder.doGetPids(); return builder.doGetPids();

View File

@ -64,21 +64,23 @@ public interface IDao {
FhirContext getContext(); FhirContext getContext();
RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName);
Collection<RuntimeSearchParam> getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef);
/** /**
* Populate all of the runtime dependencies that a bundle provider requires in order to work * Populate all of the runtime dependencies that a bundle provider requires in order to work
*/ */
void injectDependenciesIntoBundleProvider(PersistedJpaBundleProvider theProvider); void injectDependenciesIntoBundleProvider(PersistedJpaBundleProvider theProvider);
SearchBuilder newSearchBuilder();
void populateFullTextFields(IBaseResource theResource, ResourceTable theEntity);
<R extends IBaseResource> Set<Long> processMatchUrl(String theMatchUrl, Class<R> theResourceType); <R extends IBaseResource> Set<Long> processMatchUrl(String theMatchUrl, Class<R> theResourceType);
IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation); IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation);
<R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation); <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation);
void populateFullTextFields(IBaseResource theResource, ResourceTable theEntity);
RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName);
Collection<RuntimeSearchParam> getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef);
} }

View File

@ -93,20 +93,20 @@ public class SearchBuilder {
private IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao; private IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
private String myResourceName; private String myResourceName;
private Class<? extends IBaseResource> myResourceType; private Class<? extends IBaseResource> myResourceType;
private IFulltextSearchSvc mySearchDao; private IFulltextSearchSvc myFulltextSearchSvc;
private Search mySearchEntity; private Search mySearchEntity;
private ISearchResultDao mySearchResultDao; private ISearchResultDao mySearchResultDao;
private ISearchParamRegistry mySearchParamRegistry; private ISearchParamRegistry mySearchParamRegistry;
private IHapiTerminologySvc myTerminologySvc; private IHapiTerminologySvc myTerminologySvc;
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theSearchDao, public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theFulltextSearchSvc,
ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao, ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao,
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao, IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry) { IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao, IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry) {
myContext = theFhirContext; myContext = theFhirContext;
myEntityManager = theEntityManager; myEntityManager = theEntityManager;
myPlatformTransactionManager = thePlatformTransactionManager; myPlatformTransactionManager = thePlatformTransactionManager;
mySearchDao = theSearchDao; myFulltextSearchSvc = theFulltextSearchSvc;
mySearchResultDao = theSearchResultDao; mySearchResultDao = theSearchResultDao;
myCallingDao = theDao; myCallingDao = theDao;
myResourceIndexedSearchParamUriDao = theResourceIndexedSearchParamUriDao; myResourceIndexedSearchParamUriDao = theResourceIndexedSearchParamUriDao;
@ -1679,7 +1679,11 @@ public class SearchBuilder {
StopWatch w = new StopWatch(); StopWatch w = new StopWatch();
doInitializeSearch(); doInitializeSearch();
return doReturnProvider();
}
public IBundleProvider loadPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
StopWatch sw = new StopWatch();
DateRangeParam lu = theParams.getLastUpdated(); DateRangeParam lu = theParams.getLastUpdated();
// Collection<Long> loadPids; // Collection<Long> loadPids;
@ -1692,7 +1696,7 @@ public class SearchBuilder {
} }
if (theParams.containsKey(Constants.PARAM_CONTENT) || theParams.containsKey(Constants.PARAM_TEXT)) { if (theParams.containsKey(Constants.PARAM_CONTENT) || theParams.containsKey(Constants.PARAM_TEXT)) {
List<Long> pids = mySearchDao.everything(myResourceName, theParams); List<Long> pids = myFulltextSearchSvc.everything(myResourceName, theParams);
if (pids.isEmpty()) { if (pids.isEmpty()) {
return doReturnProvider(); return doReturnProvider();
} }
@ -1734,14 +1738,14 @@ public class SearchBuilder {
} else { } else {
if (mySearchDao == null) { if (myFulltextSearchSvc == null) {
if (theParams.containsKey(Constants.PARAM_TEXT)) { if (theParams.containsKey(Constants.PARAM_TEXT)) {
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT); throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
} else if (theParams.containsKey(Constants.PARAM_CONTENT)) { } else if (theParams.containsKey(Constants.PARAM_CONTENT)) {
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT); throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
} }
} else { } else {
List<Long> searchResultPids = mySearchDao.search(myResourceName, theParams); List<Long> searchResultPids = myFulltextSearchSvc.search(myResourceName, theParams);
if (searchResultPids != null) { if (searchResultPids != null) {
if (searchResultPids.isEmpty()) { if (searchResultPids.isEmpty()) {
return doReturnProvider(); return doReturnProvider();
@ -1756,15 +1760,6 @@ public class SearchBuilder {
} }
// // Load _include and _revinclude before filter and sort in everything mode
// if (theParams.getEverythingMode() != null) {
// if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
// loadPids.addAll(loadReverseIncludes(loadPids, theParams.getRevIncludes(), true,
// theParams.getEverythingMode()));
// loadPids.addAll(loadReverseIncludes(loadPids, theParams.getIncludes(), false, theParams.getEverythingMode()));
// }
// }
if (doHaveNoResults()) { if (doHaveNoResults()) {
return doReturnProvider(); return doReturnProvider();
} }
@ -1781,8 +1776,9 @@ public class SearchBuilder {
// Handle sorting if any was provided // Handle sorting if any was provided
processSort(theParams); processSort(theParams);
ourLog.info(" {} on {} in {}ms", new Object[] { myResourceName, theParams, w.getMillisAndRestart() }); ourLog.info(" {} on {} in {}ms", new Object[] { myResourceName, theParams, sw.getMillisAndRestart() });
return doReturnProvider(); return doReturnProvider();
} }
private void searchForIdsWithAndOr(SearchParameterMap theParams, DateRangeParam theLastUpdated) { private void searchForIdsWithAndOr(SearchParameterMap theParams, DateRangeParam theLastUpdated) {

View File

@ -29,6 +29,7 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import org.apache.commons.lang3.SerializationUtils;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
@ -41,6 +42,7 @@ import org.springframework.transaction.support.TransactionTemplate;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.IDao; import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.SearchBuilder; import ca.uhn.fhir.jpa.dao.SearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.data.ISearchDao; import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao; import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.*; import ca.uhn.fhir.jpa.entity.*;
@ -113,6 +115,10 @@ public final class PersistedJpaBundleProvider implements IBundleProvider {
} }
protected List<IBaseResource> doSearchOrEverythingInTransaction(final int theFromIndex, final int theToIndex) { protected List<IBaseResource> doSearchOrEverythingInTransaction(final int theFromIndex, final int theToIndex) {
SearchBuilder sb = myDao.newSearchBuilder();
SearchParameterMap parameterMap = SerializationUtils.deserialize(mySearchEntity.getSearchParamMap());
sb.loadPage(parameterMap, theFromIndex, theToIndex);
Pageable page = toPage(theFromIndex, theToIndex); Pageable page = toPage(theFromIndex, theToIndex);
if (page == null) { if (page == null) {
@ -246,7 +252,7 @@ public final class PersistedJpaBundleProvider implements IBundleProvider {
return Math.max(0, mySearchEntity.getTotalCount()); return Math.max(0, mySearchEntity.getTotalCount());
} }
public static Pageable toPage(final int theFromIndex, int theToIndex) { static Pageable toPage(final int theFromIndex, int theToIndex) {
int pageSize = theToIndex - theFromIndex; int pageSize = theToIndex - theFromIndex;
if (pageSize < 1) { if (pageSize < 1) {
return null; return null;

View File

@ -2,12 +2,14 @@ package ca.uhn.fhir.jpa.search;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
public class PersistedJpaBundleProviderTest { public class PersistedJpaBundleProviderTest {
@Test @Test
@Ignore
public void testGetPage() { public void testGetPage() {
Pageable page = PersistedJpaBundleProvider.toPage(50, 73); Pageable page = PersistedJpaBundleProvider.toPage(50, 73);
assertEquals(50, page.getOffset()); assertEquals(50, page.getOffset());