Merge pull request #975 from jamesagnew/963_jpa_performance

963 jpa performance
This commit is contained in:
Frank Tao 2018-06-19 21:47:26 -04:00 committed by GitHub
commit 32e1feb484
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 240 additions and 71 deletions

View File

@ -1174,7 +1174,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
public SearchBuilder newSearchBuilder() {
SearchBuilder builder = new SearchBuilder(getContext(), myEntityManager, myFulltextSearchSvc, this, myResourceIndexedSearchParamUriDao,
myForcedIdDao,
myTerminologySvc, mySerarchParamRegistry);
myTerminologySvc, mySerarchParamRegistry, myResourceHistoryTableDao, myResourceTagDao);
return builder;
}
@ -1355,7 +1355,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
@SuppressWarnings("unchecked")
private <R extends IBaseResource> R populateResourceMetadataHapi(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation, IResource res) {
private <R extends IBaseResource> R populateResourceMetadataHapi(Class<R> theResourceType, BaseHasResource theEntity, Collection<? extends BaseTag> theTagList, boolean theForHistoryOperation, IResource res) {
R retVal = (R) res;
if (theEntity.getDeleted() != null) {
res = (IResource) myContext.getResourceDefinition(theResourceType).newInstance();
@ -1384,7 +1384,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
ResourceMetadataKeyEnum.UPDATED.put(res, theEntity.getUpdated());
IDao.RESOURCE_PID.put(res, theEntity.getId());
Collection<? extends BaseTag> tags = theEntity.getTags();
Collection<? extends BaseTag> tags = theTagList;
if (theEntity.isHasTags()) {
TagList tagList = new TagList();
List<IBaseCoding> securityLabels = new ArrayList<>();
@ -1421,7 +1421,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
@SuppressWarnings("unchecked")
private <R extends IBaseResource> R populateResourceMetadataRi(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation, IAnyResource res) {
private <R extends IBaseResource> R populateResourceMetadataRi(Class<R> theResourceType, BaseHasResource theEntity, Collection<? extends BaseTag> theTagList, boolean theForHistoryOperation, IAnyResource res) {
R retVal = (R) res;
if (theEntity.getDeleted() != null) {
res = (IAnyResource) myContext.getResourceDefinition(theResourceType).newInstance();
@ -1454,7 +1454,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
res.getMeta().setLastUpdated(theEntity.getUpdatedDate());
IDao.RESOURCE_PID.put(res, theEntity.getId());
Collection<? extends BaseTag> tags = theEntity.getTags();
Collection<? extends BaseTag> tags = theTagList;
if (theEntity.isHasTags()) {
for (BaseTag next : tags) {
@ -1601,19 +1601,25 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
public IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation) {
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
Class<? extends IBaseResource> resourceType = type.getImplementingClass();
return toResource(resourceType, theEntity, theForHistoryOperation);
return toResource(resourceType, theEntity, null, null, theForHistoryOperation);
}
@SuppressWarnings("unchecked")
@Override
public <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity,
public <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, ResourceHistoryTable theHistory, Collection<ResourceTag> theTagList,
boolean theForHistoryOperation) {
// May 28, 2018 - #936
// Could set historyList to null, if it's not called in the loop for the backward compatibility
ResourceHistoryTable history;
if (theEntity instanceof ResourceHistoryTable) {
history = (ResourceHistoryTable) theEntity;
} else {
history = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
if (theHistory == null) {
history = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
} else {
history = theHistory;
}
}
if (history == null) {
@ -1639,12 +1645,21 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
break;
}
// get preload the tagList
Collection<? extends BaseTag> myTagList;
if (theTagList == null)
myTagList = theEntity.getTags();
else
myTagList = theTagList;
/*
* Use the appropriate custom type if one is specified in the context
*/
Class<R> resourceType = theResourceType;
if (myContext.hasDefaultTypeForProfile()) {
for (BaseTag nextTag : theEntity.getTags()) {
for (BaseTag nextTag : myTagList) {
if (nextTag.getTag().getTagType() == TagTypeEnum.PROFILE) {
String profile = nextTag.getTag().getCode();
if (isNotBlank(profile)) {
@ -1691,10 +1706,10 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
if (retVal instanceof IResource) {
IResource res = (IResource) retVal;
retVal = populateResourceMetadataHapi(resourceType, theEntity, theForHistoryOperation, res);
retVal = populateResourceMetadataHapi(resourceType, theEntity, myTagList, theForHistoryOperation, res);
} else {
IAnyResource res = (IAnyResource) retVal;
retVal = populateResourceMetadataRi(resourceType, theEntity, theForHistoryOperation, res);
retVal = populateResourceMetadataRi(resourceType, theEntity, myTagList, theForHistoryOperation, res);
}
@ -1730,7 +1745,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
return theResourceType + '/' + theId.toString();
}
}
@SuppressWarnings("unchecked")
protected ResourceTable updateEntity(RequestDetails theRequest, final IBaseResource theResource, ResourceTable
theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,

View File

@ -207,7 +207,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
StopWatch w = new StopWatch();
T resourceToDelete = toResource(myResourceType, entity, false);
T resourceToDelete = toResource(myResourceType, entity, null, null, false);
// Notify IServerOperationInterceptors about pre-action call
if (theReques != null) {
@ -289,7 +289,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
deletedResources.add(entity);
T resourceToDelete = toResource(myResourceType, entity, false);
T resourceToDelete = toResource(myResourceType, entity, null, null, false);
// Notify IServerOperationInterceptors about pre-action call
if (theRequest != null) {
@ -854,7 +854,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
BaseHasResource entity = readEntity(theId);
validateResourceType(entity);
T retVal = toResource(myResourceType, entity, false);
T retVal = toResource(myResourceType, entity, null, null, false);
IPrimitiveType<Date> deleted;
if (retVal instanceof IResource) {

View File

@ -1,15 +1,18 @@
package ca.uhn.fhir.jpa.dao;
import java.util.Collection;
import java.util.Set;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.entity.BaseHasResource;
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.ResourceTag;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.Collection;
import java.util.Set;
/*
* #%L
@ -56,6 +59,6 @@ public interface IDao {
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, ResourceHistoryTable theHistory, Collection<ResourceTag> theTagList, boolean theForHistoryOperation);
}

View File

@ -1,5 +1,58 @@
package ca.uhn.fhir.jpa.dao;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaBuilder.In;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.tuple.Pair;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.query.Query;
import org.hl7.fhir.dstu3.model.BaseResource;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/*
* #%L
* HAPI FHIR JPA Server
@ -19,17 +72,45 @@ package ca.uhn.fhir.jpa.dao;
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
import ca.uhn.fhir.jpa.entity.BaseHasResource;
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri;
import ca.uhn.fhir.jpa.entity.ResourceLink;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.ResourceTag;
import ca.uhn.fhir.jpa.entity.SearchParam;
import ca.uhn.fhir.jpa.entity.SearchParamPresent;
import ca.uhn.fhir.jpa.entity.TagDefinition;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.jpa.util.BaseIterator;
import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
@ -41,41 +122,25 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.param.CompositeParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.HasParam;
import ca.uhn.fhir.rest.param.NumberParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.param.TokenParamModifier;
import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.param.UriParamQualifierEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.UrlUtil;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.tuple.Pair;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.query.Query;
import org.hl7.fhir.dstu3.model.BaseResource;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import javax.persistence.criteria.CriteriaBuilder.In;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.*;
import java.util.Map.Entry;
import static org.apache.commons.lang3.StringUtils.*;
/**
* The SearchBuilder is responsible for actually forming the SQL query that handles
@ -108,12 +173,17 @@ public class SearchBuilder implements ISearchBuilder {
private IHapiTerminologySvc myTerminologySvc;
private int myFetchSize;
protected IResourceHistoryTableDao myResourceHistoryTableDao;
protected IResourceTagDao myResourceTagDao;
/**
* Constructor
*/
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, IFulltextSearchSvc theFulltextSearchSvc,
BaseHapiFhirDao<?> theDao,
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao, IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry) {
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager,
IFulltextSearchSvc theFulltextSearchSvc, BaseHapiFhirDao<?> theDao,
IResourceIndexedSearchParamUriDao theResourceIndexedSearchParamUriDao, IForcedIdDao theForcedIdDao,
IHapiTerminologySvc theTerminologySvc, ISearchParamRegistry theSearchParamRegistry,
IResourceHistoryTableDao theResourceHistoryTableDao, IResourceTagDao theResourceTagDao) {
myContext = theFhirContext;
myEntityManager = theEntityManager;
myFulltextSearchSvc = theFulltextSearchSvc;
@ -122,6 +192,8 @@ public class SearchBuilder implements ISearchBuilder {
myForcedIdDao = theForcedIdDao;
myTerminologySvc = theTerminologySvc;
mySearchParamRegistry = theSearchParamRegistry;
myResourceHistoryTableDao = theResourceHistoryTableDao;
myResourceTagDao = theResourceTagDao;
}
private void addPredicateComposite(String theResourceName, RuntimeSearchParam theParamDef, List<? extends IQueryParameterType> theNextAnd) {
@ -1610,9 +1682,15 @@ public class SearchBuilder implements ISearchBuilder {
List<ResourceTable> resultList = q.getResultList();
//-- Issue #963: Load resource histories based on pids once to improve the performance
Map<Long, ResourceHistoryTable> historyMap = getResourceHistoryMap(pids);
//-- preload all tags with tag definition if any
Map<Long, Collection<ResourceTag>> tagMap = getResourceTagMap(resultList);
for (ResourceTable next : resultList) {
Class<? extends IBaseResource> resourceType = context.getResourceDefinition(next.getResourceType()).getImplementingClass();
IBaseResource resource = theDao.toResource(resourceType, next, theForHistoryOperation);
IBaseResource resource = theDao.toResource(resourceType, next, historyMap.get(next.getId()), tagMap.get(next.getId()), theForHistoryOperation);
if (resource == null) {
ourLog.warn("Unable to find resource {}/{}/_history/{} in database", next.getResourceType(), next.getIdDt().getIdPart(), next.getVersion());
continue;
@ -1641,6 +1719,62 @@ public class SearchBuilder implements ISearchBuilder {
}
}
//-- load all history in to the map
private Map<Long, ResourceHistoryTable> getResourceHistoryMap(Collection<Long> pids) {
Map<Long, ResourceHistoryTable> historyMap = new HashMap<Long, ResourceHistoryTable>();
if (pids.size() == 0)
return historyMap;
Collection<ResourceHistoryTable> historyList = myResourceHistoryTableDao.findByResourceIds(pids);
for (ResourceHistoryTable history : historyList) {
historyMap.put(history.getResourceId(), history);
}
return historyMap;
}
private Map<Long, Collection<ResourceTag>> getResourceTagMap(List<ResourceTable> resourceList) {
List<Long> idList = new ArrayList<Long>(resourceList.size());
//-- find all resource has tags
for (ResourceTable resource: resourceList) {
if (resource.isHasTags())
idList.add(resource.getId());
}
Map<Long, Collection<ResourceTag>> tagMap = new HashMap<Long, Collection<ResourceTag>>();
//-- no tags
if (idList.size() == 0)
return tagMap;
//-- get all tags for the idList
Collection<ResourceTag> tagList = myResourceTagDao.findByResourceIds(idList);
//-- build the map, key = resourceId, value = list of ResourceTag
Long resourceId;
Collection<ResourceTag> tagCol;
for (ResourceTag tag : tagList) {
resourceId = tag.getResourceId();
tagCol = tagMap.get(resourceId);
if (tagCol == null) {
tagCol = new ArrayList<ResourceTag>();
tagCol.add(tag);
tagMap.put(resourceId, tagCol);
} else {
tagCol.add(tag);
}
}
return tagMap;
}
@Override
public void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation,
EntityManager entityManager, FhirContext context, IDao theDao) {

View File

@ -1,6 +1,10 @@
package ca.uhn.fhir.jpa.dao.data;
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.TemporalType;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;
@ -8,8 +12,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.Temporal;
import org.springframework.data.repository.query.Param;
import javax.persistence.TemporalType;
import java.util.Date;
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
/*
* #%L
@ -82,4 +85,10 @@ public interface IResourceHistoryTableDao extends JpaRepository<ResourceHistoryT
"LEFT OUTER JOIN ResourceTable t ON (v.myResourceId = t.myId) " +
"WHERE v.myResourceVersion != t.myVersion")
Slice<Long> findIdsOfPreviousVersionsOfResources(Pageable thePage);
@Query("" +
"SELECT h FROM ResourceHistoryTable h " +
"INNER JOIN ResourceTable r ON (r.myId = h.myResourceId and r.myVersion = h.myResourceVersion) " +
"WHERE r.myId in (:pids)")
Collection<ResourceHistoryTable> findByResourceIds(@Param("pids") Collection<Long> pids);
}

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.jpa.dao.data;
import java.util.Collection;
/*
* #%L
* HAPI FHIR JPA Server
@ -21,9 +23,15 @@ package ca.uhn.fhir.jpa.dao.data;
*/
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ca.uhn.fhir.jpa.entity.ResourceTag;
public interface IResourceTagDao extends JpaRepository<ResourceTag, Long> {
// nothing
@Query("" +
"SELECT t FROM ResourceTag t " +
"INNER JOIN TagDefinition td ON (td.myId = t.myTagId) " +
"WHERE t.myResourceId in (:pids)")
Collection<ResourceTag> findByResourceIds(@Param("pids") Collection<Long> pids);
}

View File

@ -38,8 +38,8 @@ public interface ISearchResultDao extends JpaRepository<SearchResult, Long> {
@Query(value="SELECT r FROM SearchResult r WHERE r.mySearch = :search")
Collection<SearchResult> findWithSearchUuid(@Param("search") Search theSearch);
@Query(value="SELECT r FROM SearchResult r WHERE r.mySearch = :search ORDER BY r.myOrder ASC")
Page<SearchResult> findWithSearchUuid(@Param("search") Search theSearch, Pageable thePage);
@Query(value="SELECT r.myResourcePid FROM SearchResult r WHERE r.mySearch = :search ORDER BY r.myOrder ASC")
Page<Long> findWithSearchUuid(@Param("search") Search theSearch, Pageable thePage);
@Modifying
@Query(value="DELETE FROM SearchResult r WHERE r.mySearchPid = :search")

View File

@ -178,9 +178,9 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
@Override
public List<Long> doInTransaction(TransactionStatus theStatus) {
final List<Long> resultPids = new ArrayList<Long>();
Page<SearchResult> searchResults = mySearchResultDao.findWithSearchUuid(foundSearch, page);
for (SearchResult next : searchResults) {
resultPids.add(next.getResourcePid());
Page<Long> searchResultPids = mySearchResultDao.findWithSearchUuid(foundSearch, page);
for (Long next : searchResultPids) {
resultPids.add(next);
}
return resultPids;
}

View File

@ -321,18 +321,18 @@ public class SearchCoordinatorSvcImplTest {
// ignore
}
when(mySearchResultDao.findWithSearchUuid(any(Search.class), any(Pageable.class))).thenAnswer(new Answer<Page<SearchResult>>() {
when(mySearchResultDao.findWithSearchUuid(any(Search.class), any(Pageable.class))).thenAnswer(new Answer<Page<Long>>() {
@Override
public Page<SearchResult> answer(InvocationOnMock theInvocation) throws Throwable {
public Page<Long> answer(InvocationOnMock theInvocation) throws Throwable {
Pageable page = (Pageable) theInvocation.getArguments()[1];
ArrayList<SearchResult> results = new ArrayList<SearchResult>();
ArrayList<Long> results = new ArrayList<Long>();
int max = (page.getPageNumber() * page.getPageSize()) + page.getPageSize();
for (long i = page.getOffset(); i < max; i++) {
results.add(new SearchResult().setResourcePid(i + 10L));
results.add(i + 10L);
}
return new PageImpl<SearchResult>(results);
return new PageImpl<Long>(results);
}
});
search.setStatus(SearchStatusEnum.FINISHED);