For bit of work on JPA perf enhancements

This commit is contained in:
James Agnew 2017-03-30 06:28:34 +08:00
parent 2c9a6e65e7
commit ce73e89715
9 changed files with 125 additions and 203 deletions

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import java.io.Serializable;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -26,7 +28,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.method.QualifiedParamList; import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public interface IQueryParameterAnd<T extends IQueryParameterOr<?>> { public interface IQueryParameterAnd<T extends IQueryParameterOr<?>> extends Serializable {
/** /**
* *

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import java.io.Serializable;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -25,7 +27,7 @@ import java.util.List;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.method.QualifiedParamList; import ca.uhn.fhir.rest.method.QualifiedParamList;
public interface IQueryParameterOr<T extends IQueryParameterType> { public interface IQueryParameterOr<T extends IQueryParameterType> extends Serializable {
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters); public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters);

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import java.io.Serializable;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
/* /*
@ -22,7 +24,7 @@ import ca.uhn.fhir.context.FhirContext;
* #L% * #L%
*/ */
public interface IQueryParameterType { public interface IQueryParameterType extends Serializable {
/** /**
* This method is generally only called by HAPI itself, and should not need to be called from user code. * This method is generally only called by HAPI itself, and should not need to be called from user code.

View File

@ -952,8 +952,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Override @Override
public IBundleProvider search(final SearchParameterMap theParams) { public IBundleProvider search(final SearchParameterMap theParams) {
return search(theParams, null);
}
@Override
public IBundleProvider search(final SearchParameterMap theParams, RequestDetails theRequestDetails) {
// Notify interceptors // Notify interceptors
ActionRequestDetails requestDetails = new ActionRequestDetails(theParams.getRequestDetails(), 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 = new SearchBuilder(getContext(), myEntityManager, myPlatformTransactionManager, mySearchDao, mySearchResultDao, this, myResourceIndexedSearchParamUriDao, myForcedIdDao,

View File

@ -176,6 +176,8 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
IBundleProvider search(SearchParameterMap theMap); IBundleProvider search(SearchParameterMap theMap);
IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails);
IBundleProvider search(String theParameterName, IQueryParameterType theValue); IBundleProvider search(String theParameterName, IQueryParameterType theValue);
Set<Long> searchForIds(Map<String, IQueryParameterType> theParams); Set<Long> searchForIds(Map<String, IQueryParameterType> theParams);

View File

@ -36,6 +36,7 @@ import javax.persistence.TypedQuery;
import javax.persistence.criteria.*; import javax.persistence.criteria.*;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
@ -99,7 +100,8 @@ public class SearchBuilder {
private IHapiTerminologySvc myTerminologySvc; private IHapiTerminologySvc myTerminologySvc;
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theSearchDao, ISearchResultDao theSearchResultDao, BaseHapiFhirDao<?> theDao, public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theSearchDao,
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;
@ -325,7 +327,8 @@ public class SearchBuilder {
return; return;
} }
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates, IQueryParameterType nextOr) { private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates,
IQueryParameterType nextOr) {
boolean missingFalse = false; boolean missingFalse = false;
if (nextOr.getMissing() != null) { if (nextOr.getMissing() != null) {
if (nextOr.getMissing().booleanValue() == true) { if (nextOr.getMissing().booleanValue() == true) {
@ -339,7 +342,8 @@ public class SearchBuilder {
return missingFalse; return missingFalse;
} }
private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, Root<? extends ResourceLink> from, List<Predicate> codePredicates, IQueryParameterType nextOr) { private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, Root<? extends ResourceLink> from, List<Predicate> codePredicates,
IQueryParameterType nextOr) {
boolean missingFalse = false; boolean missingFalse = false;
if (nextOr.getMissing() != null) { if (nextOr.getMissing() != null) {
if (nextOr.getMissing().booleanValue() == true) { if (nextOr.getMissing().booleanValue() == true) {
@ -560,7 +564,7 @@ public class SearchBuilder {
BaseRuntimeChildDefinition def = myContext.newTerser().getDefinition(myResourceType, paramPath); BaseRuntimeChildDefinition def = myContext.newTerser().getDefinition(myResourceType, paramPath);
if (def instanceof RuntimeChildChoiceDefinition) { if (def instanceof RuntimeChildChoiceDefinition) {
RuntimeChildChoiceDefinition choiceDef = (RuntimeChildChoiceDefinition)def; RuntimeChildChoiceDefinition choiceDef = (RuntimeChildChoiceDefinition) def;
resourceTypes = choiceDef.getResourceTypes(); resourceTypes = choiceDef.getResourceTypes();
} else if (def instanceof RuntimeChildResourceDefinition) { } else if (def instanceof RuntimeChildResourceDefinition) {
RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def; RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def;
@ -1132,7 +1136,8 @@ public class SearchBuilder {
predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from)); predicates.addAll(createLastUpdatedPredicates(myParams.getLastUpdatedAndRemove(), builder, from));
} }
private Predicate createPredicateNumeric(CriteriaBuilder builder, IQueryParameterType params, ParamPrefixEnum cmpValue, BigDecimal valueValue, final Expression<BigDecimal> path, String invalidMessageName, String theValueString) { private Predicate createPredicateNumeric(CriteriaBuilder builder, IQueryParameterType params, ParamPrefixEnum cmpValue, BigDecimal valueValue, final Expression<BigDecimal> path,
String invalidMessageName, String theValueString) {
Predicate num; Predicate num;
switch (cmpValue) { switch (cmpValue) {
case GREATERTHAN: case GREATERTHAN:
@ -1230,7 +1235,6 @@ public class SearchBuilder {
} }
private void createPredicateResourceId(CriteriaBuilder builder, CriteriaQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) { private void createPredicateResourceId(CriteriaBuilder builder, CriteriaQuery<?> cq, List<Predicate> thePredicates, Expression<Long> theExpression) {
if (myParams.isPersistResults()) {
if (mySearchEntity.getTotalCount() > -1) { if (mySearchEntity.getTotalCount() > -1) {
Subquery<Long> subQ = cq.subquery(Long.class); Subquery<Long> subQ = cq.subquery(Long.class);
Root<SearchResult> subQfrom = subQ.from(SearchResult.class); Root<SearchResult> subQfrom = subQ.from(SearchResult.class);
@ -1240,15 +1244,10 @@ public class SearchBuilder {
thePredicates.add(theExpression.in(subQ)); thePredicates.add(theExpression.in(subQ));
} }
} else {
if (myPids != null) {
thePredicates.add(theExpression.in(myPids));
}
} }
} private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder, From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
String rawSearchTerm; String rawSearchTerm;
if (theParameter instanceof TokenParam) { if (theParameter instanceof TokenParam) {
TokenParam id = (TokenParam) theParameter; TokenParam id = (TokenParam) theParameter;
@ -1267,7 +1266,8 @@ public class SearchBuilder {
} }
if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
throw new InvalidRequestException("Parameter[" + theParamName + "] has length (" + rawSearchTerm.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm); throw new InvalidRequestException("Parameter[" + theParamName + "] has length (" + rawSearchTerm.length() + ") that is longer than maximum allowed ("
+ ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
} }
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm); String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
@ -1297,7 +1297,8 @@ public class SearchBuilder {
return orPredicates; return orPredicates;
} }
private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder, From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> theFrom) { private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> theFrom) {
String code; String code;
String system; String system;
TokenParamModifier modifier = null; TokenParamModifier modifier = null;
@ -1319,11 +1320,13 @@ public class SearchBuilder {
} }
if (system != null && system.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) { if (system != null && system.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
throw new InvalidRequestException("Parameter[" + theParamName + "] has system (" + system.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + system); throw new InvalidRequestException(
"Parameter[" + theParamName + "] has system (" + system.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + system);
} }
if (code != null && code.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) { if (code != null && code.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
throw new InvalidRequestException("Parameter[" + theParamName + "] has code (" + code.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + code); throw new InvalidRequestException(
"Parameter[" + theParamName + "] has code (" + code.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + code);
} }
/* /*
@ -1533,25 +1536,16 @@ public class SearchBuilder {
} }
public Set<Long> doGetPids() { public Set<Long> doGetPids() {
if (myParams.isPersistResults()) {
HashSet<Long> retVal = new HashSet<Long>(); HashSet<Long> retVal = new HashSet<Long>();
for (SearchResult next : mySearchResultDao.findWithSearchUuid(mySearchEntity)) { for (SearchResult next : mySearchResultDao.findWithSearchUuid(mySearchEntity)) {
retVal.add(next.getResourcePid()); retVal.add(next.getResourcePid());
} }
return retVal; return retVal;
} else {
return new HashSet<Long>(myPids);
}
} }
private boolean doHaveNoResults() { private boolean doHaveNoResults() {
if (myParams.isPersistResults()) {
return mySearchEntity.getTotalCount() == 0; return mySearchEntity.getTotalCount() == 0;
} else {
return myPids != null && myPids.isEmpty();
}
} }
private void doInitializeSearch() { private void doInitializeSearch() {
@ -1561,19 +1555,10 @@ public class SearchBuilder {
} }
private IBundleProvider doReturnProvider() { private IBundleProvider doReturnProvider() {
if (myParams.isPersistResults()) {
return new PersistedJpaBundleProvider(mySearchEntity.getUuid(), myCallingDao); return new PersistedJpaBundleProvider(mySearchEntity.getUuid(), myCallingDao);
} else {
if (myPids == null) {
return new SimpleBundleProvider();
} else {
return new BundleProviderInMemory(myPids);
}
}
} }
private void doSetPids(Collection<Long> thePids) { private void doSetPids(Collection<Long> thePids) {
if (myParams.isPersistResults()) {
if (mySearchEntity.getTotalCount() != null) { if (mySearchEntity.getTotalCount() != null) {
reinitializeSearch(); reinitializeSearch();
} }
@ -1593,10 +1578,6 @@ public class SearchBuilder {
mySearchEntity = myEntityManager.merge(mySearchEntity); mySearchEntity = myEntityManager.merge(mySearchEntity);
myEntityManager.flush(); myEntityManager.flush();
} else {
myPids = thePids;
}
} }
private void filterResourceIdsByLastUpdated(final DateRangeParam theLastUpdated) { private void filterResourceIdsByLastUpdated(final DateRangeParam theLastUpdated) {
@ -1675,6 +1656,7 @@ public class SearchBuilder {
mySearchEntity.setUuid(UUID.randomUUID().toString()); mySearchEntity.setUuid(UUID.randomUUID().toString());
mySearchEntity.setCreated(new Date()); mySearchEntity.setCreated(new Date());
mySearchEntity.setTotalCount(-1); mySearchEntity.setTotalCount(-1);
mySearchEntity.setSearchParamMap(SerializationUtils.serialize(myParams));
mySearchEntity.setPreferredPageSize(myParams.getCount()); mySearchEntity.setPreferredPageSize(myParams.getCount());
mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH); mySearchEntity.setSearchType(myParams.getEverythingMode() != null ? SearchTypeEnum.EVERYTHING : SearchTypeEnum.SEARCH);
mySearchEntity.setLastUpdated(myParams.getLastUpdated()); mySearchEntity.setLastUpdated(myParams.getLastUpdated());
@ -1686,13 +1668,11 @@ public class SearchBuilder {
mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse())); mySearchEntity.getIncludes().add(new SearchInclude(mySearchEntity, next.getValue(), true, next.isRecurse()));
} }
if (myParams.isPersistResults()) {
myEntityManager.persist(mySearchEntity); myEntityManager.persist(mySearchEntity);
for (SearchInclude next : mySearchEntity.getIncludes()) { for (SearchInclude next : mySearchEntity.getIncludes()) {
myEntityManager.persist(next); myEntityManager.persist(next);
} }
} }
}
public IBundleProvider search(final SearchParameterMap theParams) { public IBundleProvider search(final SearchParameterMap theParams) {
myParams = theParams; myParams = theParams;
@ -1814,7 +1794,7 @@ public class SearchBuilder {
doInitializeSearch(); doInitializeSearch();
// RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(myResourceType); // RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(myResourceType);
for (Entry<String, List<List<? extends IQueryParameterType>>> nextParamEntry : params.entrySet()) { for (Entry<String, List<List<? extends IQueryParameterType>>> nextParamEntry : params.entrySet()) {
String nextParamName = nextParamEntry.getKey(); String nextParamName = nextParamEntry.getKey();
@ -2038,7 +2018,8 @@ public class SearchBuilder {
return likeExpression.replace("%", "[%]") + "%"; return likeExpression.replace("%", "[%]") + "%";
} }
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, Root<? extends ResourceLink> from, Class<? extends IBaseResource> resourceType) { private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, Root<? extends ResourceLink> from,
Class<? extends IBaseResource> resourceType) {
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType); RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(resourceType);
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName); RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
List<String> path = param.getPathsSplit(); List<String> path = param.getPathsSplit();
@ -2062,7 +2043,8 @@ public class SearchBuilder {
return resultList; return resultList;
} }
public static void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation, EntityManager entityManager, FhirContext context, IDao theDao) { public static void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation,
EntityManager entityManager, FhirContext context, IDao theDao) {
if (theIncludePids.isEmpty()) { if (theIncludePids.isEmpty()) {
return; return;
} }
@ -2111,7 +2093,8 @@ public class SearchBuilder {
* *
* @param theLastUpdated * @param theLastUpdated
*/ */
public static HashSet<Long> loadReverseIncludes(IDao theCallingDao, FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode, DateRangeParam theLastUpdated) { public static HashSet<Long> loadReverseIncludes(IDao theCallingDao, FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes,
boolean theReverseMode, DateRangeParam theLastUpdated) {
if (theMatches.size() == 0) { if (theMatches.size() == 0) {
return new HashSet<Long>(); return new HashSet<Long>();
} }
@ -2253,65 +2236,4 @@ public class SearchBuilder {
return thePredicates.toArray(new Predicate[thePredicates.size()]); return thePredicates.toArray(new Predicate[thePredicates.size()]);
} }
private final class BundleProviderInMemory implements IBundleProvider {
private final ArrayList<Long> myPids;
private BundleProviderInMemory(Collection<Long> thePids) {
final ArrayList<Long> pids;
if (!(thePids instanceof List)) {
pids = new ArrayList<Long>(thePids);
} else {
pids = (ArrayList<Long>) thePids;
}
myPids = pids;
}
@Override
public InstantDt getPublished() {
return new InstantDt(mySearchEntity.getCreated());
}
@Override
public List<IBaseResource> getResources(final int theFromIndex, final int theToIndex) {
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
return template.execute(new TransactionCallback<List<IBaseResource>>() {
@Override
public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
List<Long> pidsSubList = myPids.subList(theFromIndex, theToIndex);
// Load includes
pidsSubList = new ArrayList<Long>(pidsSubList);
Set<Long> revIncludedPids = new HashSet<Long>();
if (myParams.getEverythingMode() == null) {
revIncludedPids.addAll(loadReverseIncludes(myCallingDao, myContext, myEntityManager, pidsSubList, myParams.getRevIncludes(), true, myParams.getLastUpdated()));
}
revIncludedPids.addAll(loadReverseIncludes(myCallingDao, myContext, myEntityManager, pidsSubList, myParams.getIncludes(), false, myParams.getLastUpdated()));
// Execute the query and make sure we return distinct results
List<IBaseResource> resources = new ArrayList<IBaseResource>();
loadResourcesByPid(pidsSubList, resources, revIncludedPids, false);
return resources;
}
});
}
@Override
public Integer preferredPageSize() {
return myParams.getCount();
}
@Override
public int size() {
return myPids.size();
}
@Override
public String getUuid() {
return null;
}
}
} }

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.jpa.dao; package ca.uhn.fhir.jpa.dao;
import java.io.Serializable;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -38,7 +40,7 @@ import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
public class SearchParameterMap extends LinkedHashMap<String, List<List<? extends IQueryParameterType>>> { public class SearchParameterMap extends LinkedHashMap<String, List<List<? extends IQueryParameterType>>> implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -46,8 +48,6 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
private EverythingModeEnum myEverythingMode = null; private EverythingModeEnum myEverythingMode = null;
private Set<Include> myIncludes; private Set<Include> myIncludes;
private DateRangeParam myLastUpdated; private DateRangeParam myLastUpdated;
private boolean myPersistResults = true;
private RequestDetails myRequestDetails;
private Set<Include> myRevIncludes; private Set<Include> myRevIncludes;
private SortSpec mySort; private SortSpec mySort;
@ -137,10 +137,6 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
return retVal; return retVal;
} }
public RequestDetails getRequestDetails() {
return myRequestDetails;
}
public Set<Include> getRevIncludes() { public Set<Include> getRevIncludes() {
if (myRevIncludes == null) { if (myRevIncludes == null) {
myRevIncludes = new HashSet<Include>(); myRevIncludes = new HashSet<Include>();
@ -152,10 +148,6 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
return mySort; return mySort;
} }
public boolean isPersistResults() {
return myPersistResults;
}
public void setCount(Integer theCount) { public void setCount(Integer theCount) {
myCount = theCount; myCount = theCount;
} }
@ -173,14 +165,11 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
} }
/** /**
* Should results be persisted into a table for paging * @deprecated As of HAPI FHIR 2.4 this method no longer does anything
*/ */
@Deprecated
public void setPersistResults(boolean thePersistResults) { public void setPersistResults(boolean thePersistResults) {
myPersistResults = thePersistResults; // does nothing as of HAPI FHIR 2.4
}
public void setRequestDetails(RequestDetails theRequestDetails) {
myRequestDetails = theRequestDetails;
} }
public void setRevIncludes(Set<Include> theRevIncludes) { public void setRevIncludes(Set<Include> theRevIncludes) {

View File

@ -28,20 +28,7 @@ import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.Column; import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
@ -91,6 +78,10 @@ public class Search implements Serializable {
@OneToMany(mappedBy="mySearch") @OneToMany(mappedBy="mySearch")
private Collection<SearchResult> myResults; private Collection<SearchResult> myResults;
@Lob
@Column(name="SEARCH_PARAM_MAP", nullable=true)
private byte[] mySearchParamMap;
@Enumerated(EnumType.ORDINAL) @Enumerated(EnumType.ORDINAL)
@Column(name="SEARCH_TYPE", nullable=false) @Column(name="SEARCH_TYPE", nullable=false)
private SearchTypeEnum mySearchType; private SearchTypeEnum mySearchType;
@ -116,14 +107,6 @@ public class Search implements Serializable {
return myIncludes; return myIncludes;
} }
public Date getLastUpdatedHigh() {
return myLastUpdatedHigh;
}
public Date getLastUpdatedLow() {
return myLastUpdatedLow;
}
public DateRangeParam getLastUpdated() { public DateRangeParam getLastUpdated() {
if (myLastUpdatedLow == null && myLastUpdatedHigh == null) { if (myLastUpdatedLow == null && myLastUpdatedHigh == null) {
return null; return null;
@ -132,6 +115,14 @@ public class Search implements Serializable {
} }
} }
public Date getLastUpdatedHigh() {
return myLastUpdatedHigh;
}
public Date getLastUpdatedLow() {
return myLastUpdatedLow;
}
public Integer getPreferredPageSize() { public Integer getPreferredPageSize() {
return myPreferredPageSize; return myPreferredPageSize;
} }
@ -144,15 +135,19 @@ public class Search implements Serializable {
return myResourceType; return myResourceType;
} }
public byte[] getSearchParamMap() {
return mySearchParamMap;
}
public SearchTypeEnum getSearchType() { public SearchTypeEnum getSearchType() {
return mySearchType; return mySearchType;
} }
public Integer getTotalCount() { public Integer getTotalCount() {
return myTotalCount; return myTotalCount;
} }
public String getUuid() { public String getUuid() {
return myUuid; return myUuid;
} }
@ -160,11 +155,11 @@ public class Search implements Serializable {
public void setCreated(Date theCreated) { public void setCreated(Date theCreated) {
myCreated = theCreated; myCreated = theCreated;
} }
public void setLastUpdated(Date theLowerBound, Date theUpperBound) { public void setLastUpdated(Date theLowerBound, Date theUpperBound) {
myLastUpdatedLow = theLowerBound; myLastUpdatedLow = theLowerBound;
myLastUpdatedHigh = theUpperBound; myLastUpdatedHigh = theUpperBound;
} }
public void setLastUpdated(DateRangeParam theLastUpdated) { public void setLastUpdated(DateRangeParam theLastUpdated) {
if (theLastUpdated == null) { if (theLastUpdated == null) {
myLastUpdatedLow = null; myLastUpdatedLow = null;
@ -183,11 +178,15 @@ public class Search implements Serializable {
myResourceId = theResourceId; myResourceId = theResourceId;
} }
public void setResourceType(String theResourceType) { public void setResourceType(String theResourceType) {
myResourceType = theResourceType; myResourceType = theResourceType;
} }
public void setSearchParamMap(byte[] theSearchParamMap) {
mySearchParamMap = theSearchParamMap;
}
public void setSearchType(SearchTypeEnum theSearchType) { public void setSearchType(SearchTypeEnum theSearchType) {
mySearchType = theSearchType; mySearchType = theSearchType;
} }

View File

@ -152,11 +152,10 @@ public class ${className}ResourceProvider extends
paramMap.setIncludes(theIncludes); paramMap.setIncludes(theIncludes);
paramMap.setSort(theSort); paramMap.setSort(theSort);
paramMap.setCount(theCount); paramMap.setCount(theCount);
paramMap.setRequestDetails(theRequestDetails);
getDao().translateRawParameters(theAdditionalRawParams, paramMap); getDao().translateRawParameters(theAdditionalRawParams, paramMap);
ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap); ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap, theRequestDetails);
return retVal; return retVal;
} finally { } finally {
endRequest(theServletRequest); endRequest(theServletRequest);