diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2799-fix-transaction-scoping-in-postgres.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2799-fix-transaction-scoping-in-postgres.yaml new file mode 100644 index 00000000000..36e0439689a --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2799-fix-transaction-scoping-in-postgres.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 2799 +title: "Certain ValueSet validation/expansion operations failed with a 'no transaction' error on + Postgresql. This has been corrected. Thanks to @tyfoni-systematic for reporting!" diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java index 5edc7ef9e23..8381d417a82 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java @@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory; import org.springframework.batch.item.ItemWriter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.transaction.support.TransactionSynchronizationManager; import java.util.List; @@ -51,6 +52,7 @@ public class BulkImportFileWriter implements ItemWriter @SuppressWarnings({"SwitchStatementWithTooFewBranches", "rawtypes", "unchecked"}) @Override public void write(List theItemLists) throws Exception { + assert TransactionSynchronizationManager.isActualTransactionActive(); String offsets = "unknown"; if (theItemLists.size() > 0) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java index 019b5db8ed1..d30f1d7f095 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java @@ -34,8 +34,11 @@ import org.springframework.batch.core.configuration.annotation.StepBuilderFactor import org.springframework.batch.core.configuration.annotation.StepScope; import org.springframework.batch.core.partition.PartitionHandler; import org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler; +import org.springframework.batch.core.step.item.KeyGenerator; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.repeat.CompletionPolicy; +import org.springframework.batch.repeat.RepeatContext; +import org.springframework.batch.repeat.exception.ExceptionHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java index 014ec74a92b..792cb351668 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java @@ -69,10 +69,15 @@ public class BulkImportStepListener implements StepExecutionListener, RetryListe message.append("Error: ").append(nextErrorMessage).append("\n"); } + theStepExecution.addFailureException(new RuntimeException(message.toString())); + myBulkDataImportSvc.setJobToStatus(jobUuid, BulkImportJobStatusEnum.ERROR, message.toString()); + ExitStatus exitStatus = ExitStatus.FAILED.addExitDescription(message.toString()); + theStepExecution.setExitStatus(exitStatus); + // Replace the built-in error message with a better one - return ExitStatus.FAILED.addExitDescription(message.toString()); + return exitStatus; } return theStepExecution.getExitStatus(); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcDaoImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcDaoImpl.java index 3aa68936218..403052760fa 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcDaoImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/cache/ResourceVersionSvcDaoImpl.java @@ -34,6 +34,7 @@ import org.hl7.fhir.instance.model.api.IIdType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Nonnull; import java.util.ArrayList; @@ -62,6 +63,7 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc { @Override @Nonnull + @Transactional public ResourceVersionMap getVersionMap(RequestPartitionId theRequestPartitionId, String theResourceName, SearchParameterMap theSearchParamMap) { IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResourceName); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java index 6d357e5482d..a7e26212c3e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java @@ -203,7 +203,7 @@ import java.util.Date; @Configuration -@EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data") +@EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data", enableDefaultTransactions=true) @Import({ SearchParamConfig.class, BatchJobsConfig.class }) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 4d82ba15b50..2dc92b860b5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -271,10 +271,12 @@ public abstract class BaseHapiFhirResourceDao extends B ResourcePersistentId pid = match.iterator().next(); Supplier entitySupplier = () -> { - ResourceTable foundEntity = myEntityManager.find(ResourceTable.class, pid.getId()); - IBaseResource resource = toResource(foundEntity, false); - theResource.setId(resource.getIdElement().getValue()); - return new LazyDaoMethodOutcome.EntityAndResource(foundEntity, resource); + return myTxTemplate.execute(tx -> { + ResourceTable foundEntity = myEntityManager.find(ResourceTable.class, pid.getId()); + IBaseResource resource = toResource(foundEntity, false); + theResource.setId(resource.getIdElement().getValue()); + return new LazyDaoMethodOutcome.EntityAndResource(foundEntity, resource); + }); }; Supplier idSupplier = () -> { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoObservation.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoObservation.java index 3705396ee9b..15d7e59e8cc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoObservation.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDaoObservation.java @@ -35,6 +35,7 @@ import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.param.ReferenceParam; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.support.TransactionTemplate; import java.util.ArrayList; import java.util.Date; @@ -77,8 +78,10 @@ public abstract class BaseHapiFhirResourceDaoObservation fixSubjectParamsOrderForLastn(theSearchParameterMap, theRequestDetails)); + theSearchParameterMap.setSort(new SortSpec(getSubjectParamName()).setOrder(SortOrderEnum.ASC).setChain(observationCode)); } else { theSearchParameterMap.setSort(observationCode); @@ -90,7 +93,7 @@ public abstract class BaseHapiFhirResourceDaoObservation orderedSubjectReferenceMap = new TreeMap<>(); - if(theSearchParameterMap.containsKey(getSubjectParamName())) { + if (theSearchParameterMap.containsKey(getSubjectParamName())) { RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null); @@ -124,8 +127,11 @@ public abstract class BaseHapiFhirResourceDaoObservation theCode, IPrimitiveType theSystem, CodingDt theCoding, RequestDetails theRequest) { return lookupCode(theCode, theSystem, theCoding, null, theRequest); } @Nonnull @Override + @Transactional public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, CodingDt theCoding, IPrimitiveType theDisplayLanguage, RequestDetails theRequest) { boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCode = theCode != null && theCode.isEmpty() == false; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBinaryStorageEntityDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBinaryStorageEntityDao.java index 2eb6fb1e473..9de7964412c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBinaryStorageEntityDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBinaryStorageEntityDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; import java.util.Optional; -public interface IBinaryStorageEntityDao extends JpaRepository { +public interface IBinaryStorageEntityDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT e FROM BinaryStorageEntity e WHERE e.myBlobId = :blob_id AND e.myResourceId = :resource_id") Optional findByIdAndResourceId(@Param("blob_id") String theBlobId, @Param("resource_id") String theResourceId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionDao.java index 5bcc28b4051..2c2992d3657 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionDao.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface IBulkExportCollectionDao extends JpaRepository { +public interface IBulkExportCollectionDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM BulkExportCollectionEntity t") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionFileDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionFileDao.java index b32a93fa069..e1a2656f276 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionFileDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportCollectionFileDao.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface IBulkExportCollectionFileDao extends JpaRepository { +public interface IBulkExportCollectionFileDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM BulkExportCollectionFileEntity t") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportJobDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportJobDao.java index c5bf0ddf606..5fd7bb1c4c9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportJobDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkExportJobDao.java @@ -32,7 +32,7 @@ import java.util.Optional; * #L% */ -public interface IBulkExportJobDao extends JpaRepository { +public interface IBulkExportJobDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT j FROM BulkExportJobEntity j WHERE j.myJobId = :jobid") Optional findByJobId(@Param("jobid") String theUuid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobDao.java index dccaa953eb8..42918ddaf4a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobDao.java @@ -30,7 +30,7 @@ import java.util.Optional; * #L% */ -public interface IBulkImportJobDao extends JpaRepository { +public interface IBulkImportJobDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT j FROM BulkImportJobEntity j WHERE j.myJobId = :jobid") Optional findByJobId(@Param("jobid") String theUuid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobFileDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobFileDao.java index 49b4f3d4ea0..8ce9b7fb2c3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobFileDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IBulkImportJobFileDao.java @@ -29,7 +29,7 @@ import java.util.Optional; * #L% */ -public interface IBulkImportJobFileDao extends JpaRepository { +public interface IBulkImportJobFileDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT f FROM BulkImportJobFileEntity f WHERE f.myJob.myJobId = :jobId ORDER BY f.myFileSequence ASC") List findAllForJob(@Param("jobId") String theJobId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java index 3a10f6be0d5..a7376549b58 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IForcedIdDao.java @@ -30,26 +30,11 @@ import java.util.Optional; * #L% */ -public interface IForcedIdDao extends JpaRepository { +public interface IForcedIdDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT f FROM ForcedId f WHERE myResourcePid IN (:resource_pids)") List findAllByResourcePid(@Param("resource_pids") List theResourcePids); - @Query("SELECT f.myResourcePid FROM ForcedId f WHERE myForcedId IN (:forced_id)") - List findByForcedId(@Param("forced_id") Collection theForcedId); - - @Query("SELECT f.myResourcePid FROM ForcedId f WHERE myResourceType = :resource_type AND myForcedId = :forced_id") - Optional findByTypeAndForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId); - - @Query("SELECT f.myResourcePid FROM ForcedId f WHERE myPartitionId.myPartitionId IS NULL AND myResourceType = :resource_type AND myForcedId = :forced_id") - Optional findByPartitionIdNullAndTypeAndForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId); - - @Query("SELECT f.myResourcePid FROM ForcedId f WHERE myPartitionId.myPartitionId IN :partition_id AND myResourceType = :resource_type AND myForcedId = :forced_id") - Optional findByPartitionIdAndTypeAndForcedId(@Param("partition_id") Collection thePartitionId, @Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId); - - @Query("SELECT f.myResourcePid FROM ForcedId f WHERE (myPartitionId.myPartitionId IN :partition_id OR myPartitionId.myPartitionId IS NULL) AND myResourceType = :resource_type AND myForcedId = :forced_id") - Optional findByPartitionIdOrNullAndTypeAndForcedId(@Param("partition_id") Collection thePartitionId, @Param("resource_type") String theResourceType, @Param("forced_id") String theForcedId); - @Query("SELECT f FROM ForcedId f WHERE f.myResourcePid = :resource_pid") Optional findByResourcePid(@Param("resource_pid") Long theResourcePid); @@ -57,48 +42,6 @@ public interface IForcedIdDao extends JpaRepository { @Query("DELETE FROM ForcedId t WHERE t.myId = :pid") void deleteByPid(@Param("pid") Long theId); - /** - * This method returns a Collection where each row is an element in the collection. Each element in the collection - * is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way. - */ - @Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE myResourceType = :resource_type AND myForcedId IN ( :forced_id )") - Collection findByTypeAndForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") Collection theForcedId); - - /** - * This method returns a Collection where each row is an element in the collection. Each element in the collection - * is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way. - */ - @Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE myPartitionIdValue IN ( :partition_id ) AND myResourceType = :resource_type AND myForcedId IN ( :forced_id )") - Collection findByTypeAndForcedIdInPartitionIds(@Param("resource_type") String theResourceType, @Param("forced_id") Collection theForcedId, @Param("partition_id") Collection thePartitionId); - - /** - * This method returns a Collection where each row is an element in the collection. Each element in the collection - * is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way. - */ - @Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE (myPartitionIdValue IS NULL OR myPartitionIdValue IN ( :partition_id )) AND myResourceType = :resource_type AND myForcedId IN ( :forced_id )") - Collection findByTypeAndForcedIdInPartitionIdsOrNullPartition(@Param("resource_type") String theResourceType, @Param("forced_id") Collection theForcedId, @Param("partition_id") Collection thePartitionId); - - /** - * This method returns a Collection where each row is an element in the collection. Each element in the collection - * is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way. - */ - @Query("SELECT f.myForcedId, f.myResourcePid FROM ForcedId f WHERE myPartitionIdValue IS NULL AND myResourceType = :resource_type AND myForcedId IN ( :forced_id )") - Collection findByTypeAndForcedIdInPartitionNull(@Param("resource_type") String theResourceType, @Param("forced_id") Collection theForcedId); - - /** - * Warning: No DB index exists for this particular query, so it may not perform well - *

- * This method returns a Collection where each row is an element in the collection. Each element in the collection - * is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way. - */ - @Query("" + - "SELECT " + - " f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " + - "FROM ForcedId f " + - "JOIN ResourceTable t ON t.myId = f.myResourcePid " + - "WHERE f.myForcedId IN ( :forced_id )") - Collection findAndResolveByForcedIdWithNoType(@Param("forced_id") Collection theForcedIds); - /** * This method returns a Collection where each row is an element in the collection. Each element in the collection * is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way. diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IHapiFhirJpaRepository.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IHapiFhirJpaRepository.java new file mode 100644 index 00000000000..8f6d0fd3032 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IHapiFhirJpaRepository.java @@ -0,0 +1,7 @@ +package ca.uhn.fhir.jpa.dao.data; + +import javax.transaction.Transactional; + +@Transactional(Transactional.TxType.MANDATORY) +public interface IHapiFhirJpaRepository { +} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java index 468dbbec24e..d1fff9497cf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java @@ -33,7 +33,7 @@ import java.util.Date; import java.util.List; @Repository -public interface IMdmLinkDao extends JpaRepository { +public interface IMdmLinkDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM MdmLink f WHERE myGoldenResourcePid = :pid OR mySourcePid = :pid") int deleteWithAnyReferenceToPid(@Param("pid") Long thePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageDao.java index 5872eb5f3b3..16269aa9853 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageDao.java @@ -27,7 +27,7 @@ import java.util.Optional; * #L% */ -public interface INpmPackageDao extends JpaRepository { +public interface INpmPackageDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT p FROM NpmPackageEntity p WHERE p.myPackageId = :id") Optional findByPackageId(@Param("id") String thePackageId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionDao.java index 1448b659a4f..9581362f06d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionDao.java @@ -29,7 +29,7 @@ import java.util.Optional; * #L% */ -public interface INpmPackageVersionDao extends JpaRepository { +public interface INpmPackageVersionDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT p FROM NpmPackageVersionEntity p WHERE p.myPackageId = :id") Collection findByPackageId(@Param("id") String thePackageId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionResourceDao.java index 40c8956c3be..2e930f9e5a2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/INpmPackageVersionResourceDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface INpmPackageVersionResourceDao extends JpaRepository { +public interface INpmPackageVersionResourceDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT e FROM NpmPackageVersionResourceEntity e WHERE e.myResourceType = :resourceType AND e.myFhirVersion = :fhirVersion AND e.myPackageVersion.myCurrentVersion = true") Slice findCurrentVersionByResourceType(Pageable thePage, @Param("fhirVersion") FhirVersionEnum theFhirVersion, @Param("resourceType") String theResourceType); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IPartitionDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IPartitionDao.java index a1daf416df0..95efe95f065 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IPartitionDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IPartitionDao.java @@ -28,7 +28,7 @@ import java.util.Optional; * #L% */ -public interface IPartitionDao extends JpaRepository { +public interface IPartitionDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT p FROM PartitionEntity p WHERE p.myName = :name") Optional findForName(@Param("name") String theName); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTableDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTableDao.java index 33ac0220074..ef2d81455cc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTableDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTableDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface IResourceHistoryTableDao extends JpaRepository { +public interface IResourceHistoryTableDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT t FROM ResourceHistoryTable t LEFT OUTER JOIN FETCH t.myProvenance WHERE t.myResourceId = :id AND t.myResourceVersion = :version") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTagDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTagDao.java index d7d868d7b06..c13d734991a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTagDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceHistoryTagDao.java @@ -28,7 +28,7 @@ import java.util.List; * #L% */ -public interface IResourceHistoryTagDao extends JpaRepository { +public interface IResourceHistoryTagDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM ResourceHistoryTag t WHERE t.myResourceHistoryPid = :historyPid") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java index 68f10e40de3..57abadc6ed9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java @@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface IResourceIndexedSearchParamCoordsDao extends JpaRepository { +public interface IResourceIndexedSearchParamCoordsDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("delete from ResourceIndexedSearchParamCoords t WHERE t.myResourcePid = :resid") void deleteByResourceId(@Param("resid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java index e251cff3597..0fc31152672 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; import java.util.List; -public interface IResourceIndexedSearchParamDateDao extends JpaRepository { +public interface IResourceIndexedSearchParamDateDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("delete from ResourceIndexedSearchParamDate t WHERE t.myResourcePid = :resid") void deleteByResourceId(@Param("resid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java index 797eb39ac55..0c98c24d35a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java @@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface IResourceIndexedSearchParamNumberDao extends JpaRepository { +public interface IResourceIndexedSearchParamNumberDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("delete from ResourceIndexedSearchParamNumber t WHERE t.myResourcePid = :resid") void deleteByResourceId(@Param("resid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java index 28a65744fb7..77fbac2ad0f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java @@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface IResourceIndexedSearchParamQuantityDao extends JpaRepository { +public interface IResourceIndexedSearchParamQuantityDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("delete from ResourceIndexedSearchParamQuantity t WHERE t.myResourcePid = :resid") void deleteByResourceId(@Param("resid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityNormalizedDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityNormalizedDao.java index a26b226cbb5..6479ca3255b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityNormalizedDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityNormalizedDao.java @@ -28,7 +28,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface IResourceIndexedSearchParamQuantityNormalizedDao extends JpaRepository { +public interface IResourceIndexedSearchParamQuantityNormalizedDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("delete from ResourceIndexedSearchParamQuantityNormalized t WHERE t.myResourcePid = :resid") void deleteByResourceId(@Param("resid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java index 326eac50911..bed32bf1e1e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; import java.util.List; -public interface IResourceIndexedSearchParamStringDao extends JpaRepository { +public interface IResourceIndexedSearchParamStringDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM ResourceIndexedSearchParamString t WHERE t.myResourcePid = :resId") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java index 7b9664221c3..9d663a1900c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java @@ -26,7 +26,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface IResourceIndexedSearchParamTokenDao extends JpaRepository { +public interface IResourceIndexedSearchParamTokenDao extends JpaRepository, IHapiFhirJpaRepository { @Query("select count(*) from ResourceIndexedSearchParamToken t WHERE t.myResourcePid = :resid") int countForResourceId(@Param("resid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamUriDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamUriDao.java index de8710475f4..0cf15345e3c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamUriDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamUriDao.java @@ -29,7 +29,7 @@ import org.springframework.data.repository.query.Param; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri; -public interface IResourceIndexedSearchParamUriDao extends JpaRepository { +public interface IResourceIndexedSearchParamUriDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT DISTINCT p.myUri FROM ResourceIndexedSearchParamUri p WHERE p.myResourceType = :resource_type AND p.myParamName = :param_name") public Collection findAllByResourceTypeAndParamName(@Param("resource_type") String theResourceType, @Param("param_name") String theParamName); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java index b492a9ef7f6..7d6902ddda3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceLinkDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; import java.util.List; -public interface IResourceLinkDao extends JpaRepository { +public interface IResourceLinkDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM ResourceLink t WHERE t.mySourceResourcePid = :resId") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceProvenanceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceProvenanceDao.java index 77dac6ae69d..a955cafb161 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceProvenanceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceProvenanceDao.java @@ -33,7 +33,7 @@ import java.util.Map; * #L% */ -public interface IResourceProvenanceDao extends JpaRepository { +public interface IResourceProvenanceDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM ResourceHistoryProvenanceEntity t WHERE t.myId = :pid") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceSearchViewDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceSearchViewDao.java index e0b27c2bda0..b68e87231c4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceSearchViewDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceSearchViewDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; import ca.uhn.fhir.jpa.entity.ResourceSearchView; -public interface IResourceSearchViewDao extends JpaRepository { +public interface IResourceSearchViewDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT v FROM ResourceSearchView v WHERE v.myResourceId in (:pids)") Collection findByResourceIds(@Param("pids") Collection pids); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java index 6ee6a307187..b77e8bbb06f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java @@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.Date; @@ -34,7 +36,8 @@ import java.util.Optional; * #L% */ -public interface IResourceTableDao extends JpaRepository { +@Transactional(propagation = Propagation.MANDATORY) +public interface IResourceTableDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT t.myId FROM ResourceTable t WHERE t.myDeleted IS NOT NULL") Slice findIdsOfDeletedResources(Pageable thePageable); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTagDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTagDao.java index d3770d128c1..006bee25fb7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTagDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTagDao.java @@ -29,7 +29,7 @@ import org.springframework.data.repository.query.Param; import ca.uhn.fhir.jpa.model.entity.ResourceTag; -public interface IResourceTagDao extends JpaRepository { +public interface IResourceTagDao extends JpaRepository, IHapiFhirJpaRepository { @Query("" + "SELECT t FROM ResourceTag t " + "INNER JOIN FETCH t.myTag td " + diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java index 03b470c8100..32db55df2f1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java @@ -32,7 +32,7 @@ import java.util.Optional; * #L% */ -public interface ISearchDao extends JpaRepository { +public interface ISearchDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT s FROM Search s LEFT OUTER JOIN FETCH s.myIncludes WHERE s.myUuid = :uuid") Optional findByUuidAndFetchIncludes(@Param("uuid") String theUuid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchIncludeDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchIncludeDao.java index 8da7e0c9913..91cc6ce7ab4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchIncludeDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchIncludeDao.java @@ -26,7 +26,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface ISearchIncludeDao extends JpaRepository { +public interface ISearchIncludeDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query(value="DELETE FROM SearchInclude r WHERE r.mySearchPid = :search") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchParamPresentDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchParamPresentDao.java index 53949ded16b..6bfd3cab722 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchParamPresentDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchParamPresentDao.java @@ -29,7 +29,7 @@ import java.util.List; * #L% */ -public interface ISearchParamPresentDao extends JpaRepository { +public interface ISearchParamPresentDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT s FROM SearchParamPresent s WHERE s.myResource = :res") List findAllForResource(@Param("res") ResourceTable theResource); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchResultDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchResultDao.java index 5cba8554d57..cf36d36b07c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchResultDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchResultDao.java @@ -31,7 +31,7 @@ import java.util.List; * #L% */ -public interface ISearchResultDao extends JpaRepository { +public interface ISearchResultDao extends JpaRepository, IHapiFhirJpaRepository { @Query(value="SELECT r.myResourcePid FROM SearchResult r WHERE r.mySearchPid = :search ORDER BY r.myOrder ASC") Slice findWithSearchPid(@Param("search") Long theSearchPid, Pageable thePage); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISubscriptionTableDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISubscriptionTableDao.java index 2a44dd1e214..27c365a761a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISubscriptionTableDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISubscriptionTableDao.java @@ -27,7 +27,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface ISubscriptionTableDao extends JpaRepository { +public interface ISubscriptionTableDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM SubscriptionTable t WHERE t.mySubscriptionResource = :subscription ") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITagDefinitionDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITagDefinitionDao.java index 202f2bf740f..168e78473f8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITagDefinitionDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITagDefinitionDao.java @@ -24,6 +24,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import ca.uhn.fhir.jpa.model.entity.TagDefinition; -public interface ITagDefinitionDao extends JpaRepository { +public interface ITagDefinitionDao extends JpaRepository, IHapiFhirJpaRepository { // nothing } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemDao.java index 618ca07a42c..2a69648f1eb 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemDao.java @@ -28,7 +28,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystem; import java.util.Optional; -public interface ITermCodeSystemDao extends JpaRepository { +public interface ITermCodeSystemDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT cs FROM TermCodeSystem cs WHERE cs.myCodeSystemUri = :code_system_uri") TermCodeSystem findByCodeSystemUri(@Param("code_system_uri") String theCodeSystemUri); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemVersionDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemVersionDao.java index e61782218f0..e622d84daa5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemVersionDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermCodeSystemVersionDao.java @@ -29,7 +29,7 @@ import java.util.List; * #L% */ -public interface ITermCodeSystemVersionDao extends JpaRepository { +public interface ITermCodeSystemVersionDao extends JpaRepository, IHapiFhirJpaRepository { @Modifying @Query("DELETE FROM TermCodeSystemVersion csv WHERE csv.myCodeSystem = :cs") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDao.java index 4574186808d..c45b79fbb87 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDao.java @@ -32,7 +32,7 @@ import java.util.Optional; * #L% */ -public interface ITermConceptDao extends JpaRepository { +public interface ITermConceptDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT COUNT(t) FROM TermConcept t WHERE t.myCodeSystem.myId = :cs_pid") Integer countByCodeSystemVersion(@Param("cs_pid") Long thePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDesignationDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDesignationDao.java index c787c9c808e..9d3db62f3d8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDesignationDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptDesignationDao.java @@ -27,7 +27,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface ITermConceptDesignationDao extends JpaRepository { +public interface ITermConceptDesignationDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT t.myId FROM TermConceptDesignation t WHERE t.myCodeSystemVersion.myId = :csv_pid") Slice findIdsByCodeSystemVersion(Pageable thePage, @Param("csv_pid") Long thePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java index 437eddac94f..c577f3362fb 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java @@ -31,7 +31,7 @@ import ca.uhn.fhir.jpa.entity.TermConceptMap; * #L% */ -public interface ITermConceptMapDao extends JpaRepository { +public interface ITermConceptMapDao extends JpaRepository, IHapiFhirJpaRepository { @Query("DELETE FROM TermConceptMap cm WHERE cm.myId = :pid") @Modifying void deleteTermConceptMapById(@Param("pid") Long theId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java index ab3f172a6ae..9b61b3f976a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface ITermConceptMapGroupDao extends JpaRepository { +public interface ITermConceptMapGroupDao extends JpaRepository, IHapiFhirJpaRepository { @Query("DELETE FROM TermConceptMapGroup g WHERE g.myId = :pid") @Modifying void deleteTermConceptMapGroupById(@Param("pid") Long theId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java index b4c4954de33..611756c8e6c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface ITermConceptMapGroupElementDao extends JpaRepository { +public interface ITermConceptMapGroupElementDao extends JpaRepository, IHapiFhirJpaRepository { @Query("DELETE FROM TermConceptMapGroupElement e WHERE e.myId = :pid") @Modifying void deleteTermConceptMapGroupElementById(@Param("pid") Long theId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java index 20ff5cef7fa..7f31d973333 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface ITermConceptMapGroupElementTargetDao extends JpaRepository { +public interface ITermConceptMapGroupElementTargetDao extends JpaRepository, IHapiFhirJpaRepository { @Query("DELETE FROM TermConceptMapGroupElementTarget t WHERE t.myId = :pid") @Modifying void deleteTermConceptMapGroupElementTargetById(@Param("pid") Long theId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptParentChildLinkDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptParentChildLinkDao.java index e95b4d9687e..4a089d9207e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptParentChildLinkDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptParentChildLinkDao.java @@ -29,7 +29,7 @@ import java.util.Collection; * #L% */ -public interface ITermConceptParentChildLinkDao extends JpaRepository { +public interface ITermConceptParentChildLinkDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT COUNT(t) FROM TermConceptParentChildLink t WHERE t.myCodeSystem.myId = :cs_pid") Integer countByCodeSystemVersion(@Param("cs_pid") Long thePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptPropertyDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptPropertyDao.java index 0dd1bb141de..a734ea83c69 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptPropertyDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptPropertyDao.java @@ -27,7 +27,7 @@ import org.springframework.data.repository.query.Param; * #L% */ -public interface ITermConceptPropertyDao extends JpaRepository { +public interface ITermConceptPropertyDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT t.myId FROM TermConceptProperty t WHERE t.myCodeSystemVersion.myId = :cs_pid") Slice findIdsByCodeSystemVersion(Pageable thePage, @Param("cs_pid") Long thePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDao.java index d5187c2b05e..d9f67f66f3c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDao.java @@ -29,7 +29,7 @@ import org.springframework.data.repository.query.Param; import java.util.List; import java.util.Optional; -public interface ITermValueSetConceptDao extends JpaRepository { +public interface ITermValueSetConceptDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT COUNT(*) FROM TermValueSetConcept vsc WHERE vsc.myValueSetPid = :pid") Integer countByTermValueSetId(@Param("pid") Long theValueSetId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDesignationDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDesignationDao.java index d8ba699efe8..c28be089371 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDesignationDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptDesignationDao.java @@ -26,7 +26,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface ITermValueSetConceptDesignationDao extends JpaRepository { +public interface ITermValueSetConceptDesignationDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT COUNT(vscd) FROM TermValueSetConceptDesignation vscd WHERE vscd.myValueSetPid = :pid") Integer countByTermValueSetId(@Param("pid") Long theValueSetId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewDao.java index e1cc3359031..df0caeb4379 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewDao.java @@ -29,7 +29,7 @@ import java.util.List; * #L% */ -public interface ITermValueSetConceptViewDao extends JpaRepository { +public interface ITermValueSetConceptViewDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT v FROM TermValueSetConceptView v WHERE v.myConceptValueSetPid = :pid AND v.myConceptOrder >= :from AND v.myConceptOrder < :to ORDER BY v.myConceptOrder") List findByTermValueSetId(@Param("from") int theFrom, @Param("to") int theTo, @Param("pid") Long theValueSetId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewOracleDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewOracleDao.java index 02ba414ee8a..25102fd8a79 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewOracleDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetConceptViewOracleDao.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; import java.io.Serializable; import java.util.List; -public interface ITermValueSetConceptViewOracleDao extends JpaRepository { +public interface ITermValueSetConceptViewOracleDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT v FROM TermValueSetConceptViewOracle v WHERE v.myConceptValueSetPid = :pid AND v.myConceptOrder >= :from AND v.myConceptOrder < :to ORDER BY v.myConceptOrder") List findByTermValueSetId(@Param("from") int theFrom, @Param("to") int theTo, @Param("pid") Long theValueSetId); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java index fd5a5bc95ce..aad329df25d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java @@ -31,7 +31,7 @@ import org.springframework.data.repository.query.Param; import java.util.List; import java.util.Optional; -public interface ITermValueSetDao extends JpaRepository { +public interface ITermValueSetDao extends JpaRepository, IHapiFhirJpaRepository { @Query("SELECT vs FROM TermValueSet vs WHERE vs.myResourcePid = :resource_pid") Optional findByResourcePid(@Param("resource_pid") Long theResourcePid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java index 5ed851dc56b..2efcbc28aca 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java @@ -47,10 +47,9 @@ 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 org.hl7.fhir.r4.model.IdType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -97,9 +96,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; */ @Service public class IdHelperService { - private static final String RESOURCE_PID = "RESOURCE_PID"; - private static final Logger ourLog = LoggerFactory.getLogger(IdHelperService.class); public static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[0]; + private static final String RESOURCE_PID = "RESOURCE_PID"; @Autowired protected IForcedIdDao myForcedIdDao; @Autowired @@ -110,6 +108,16 @@ public class IdHelperService { private FhirContext myFhirCtx; @Autowired private MemoryCacheService myMemoryCacheService; + @PersistenceContext(type = PersistenceContextType.TRANSACTION) + private EntityManager myEntityManager; + @Autowired + private PartitionSettings myPartitionSettings; + private boolean myDontCheckActiveTransactionForUnitTest; + + @VisibleForTesting + void setDontCheckActiveTransactionForUnitTest(boolean theDontCheckActiveTransactionForUnitTest) { + myDontCheckActiveTransactionForUnitTest = theDontCheckActiveTransactionForUnitTest; + } public void delete(ForcedId forcedId) { myForcedIdDao.deleteByPid(forcedId.getId()); @@ -123,6 +131,8 @@ public class IdHelperService { */ @Nonnull public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + IdDt id = new IdDt(theResourceType, theResourceId); Map> matches = translateForcedIdToPids(theRequestPartitionId, Collections.singletonList(id)); @@ -149,16 +159,12 @@ public class IdHelperService { * Returns a mapping of Id -> ResourcePersistentId. * If any resource is not found, it will throw ResourceNotFound exception * (and no map will be returned) - * - * @param theRequestPartitionId - * @param theResourceType - * @param theIds - * @return */ @Nonnull public Map resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, - String theResourceType, - List theIds) { + String theResourceType, + List theIds) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); Validate.notNull(theIds, "theIds cannot be null"); Validate.isTrue(!theIds.isEmpty(), "theIds must not be empty"); @@ -170,15 +176,13 @@ public class IdHelperService { // is already a PID retVal = new ResourcePersistentId(Long.parseLong(id)); retVals.put(id, retVal); - } - else { + } else { // is a forced id // we must resolve! if (myDaoConfig.isDeleteEnabled()) { retVal = new ResourcePersistentId(resolveResourceIdentity(theRequestPartitionId, theResourceType, id).getResourceId()); retVals.put(id, retVal); - } - else { + } else { // fetch from cache... adding to cache if not available String key = toForcedIdToPidKey(theRequestPartitionId, theResourceType, id); retVal = myMemoryCacheService.getThenPutAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, t -> { @@ -217,7 +221,7 @@ public class IdHelperService { * Returns true if the given resource ID should be stored in a forced ID. Under default config * (meaning client ID strategy is {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ALPHANUMERIC}) * this will return true if the ID has any non-digit characters. - * + *

* In {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ANY} mode it will always return true. */ public boolean idRequiresForcedId(String theId) { @@ -229,12 +233,6 @@ public class IdHelperService { return RequestPartitionId.stringifyForKey(theRequestPartitionId) + "/" + theResourceType + "/" + theId; } - @PersistenceContext(type = PersistenceContextType.TRANSACTION) - private EntityManager myEntityManager; - - @Autowired - private PartitionSettings myPartitionSettings; - /** * Given a collection of resource IDs (resource type + id), resolves the internal persistent IDs. *

@@ -243,6 +241,8 @@ public class IdHelperService { */ @Nonnull public List resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List theIds) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + for (IIdType id : theIds) { if (!id.hasIdPart()) { throw new InvalidRequestException("Parameter value missing in request"); @@ -528,6 +528,8 @@ public class IdHelperService { * @return A Set of strings representing the FHIR IDs of the pids. */ public Set translatePidsToFhirResourceIds(Set thePids) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + Map> pidToForcedIdMap = translatePidsToForcedIds(thePids); //If the result of the translation is an empty optional, it means there is no forced id, and we can use the PID as the resource ID. @@ -540,6 +542,8 @@ public class IdHelperService { } public Map> translatePidsToForcedIds(Set thePids) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + Map> retVal = new HashMap<>(myMemoryCacheService.getAllPresent(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, thePids)); List remainingPids = thePids @@ -577,6 +581,8 @@ public class IdHelperService { @Deprecated @Nullable public Long getPidOrNull(IBaseResource theResource) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + IAnyResource anyResource = (IAnyResource) theResource; Long retVal = (Long) anyResource.getUserData(RESOURCE_PID); if (retVal == null) { @@ -597,6 +603,8 @@ public class IdHelperService { @Deprecated @Nonnull public Long getPidOrThrowException(IIdType theId) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + List ids = Collections.singletonList(theId); List resourcePersistentIds = this.resolveResourcePersistentIdsWithCache(RequestPartitionId.allPartitions(), ids); return resourcePersistentIds.get(0).getIdAsLong(); @@ -609,6 +617,8 @@ public class IdHelperService { @Deprecated @Nonnull public List getPidsOrThrowException(List theIds) { + assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); + List resourcePersistentIds = this.resolveResourcePersistentIdsWithCache(RequestPartitionId.allPartitions(), theIds); return resourcePersistentIds.stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList()); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java index aa57973a90d..6a8db13d73d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java @@ -124,6 +124,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac private PartitionSettings myPartitionSettings; @Override + @Transactional public NpmPackage loadPackageFromCacheOnly(String theId, @Nullable String theVersion) { Optional packageVersion = loadPackageVersionEntity(theId, theVersion); if (!packageVersion.isPresent() && theVersion.endsWith(".x")) { @@ -338,7 +339,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac requestDetails.setTenantId(JpaConstants.DEFAULT_PARTITION_NAME); } return (ResourceTable) getBinaryDao().create(theResourceBinary, requestDetails).getEntity(); - } else { + } else { return (ResourceTable) getBinaryDao().create(theResourceBinary).getEntity(); } } @@ -388,6 +389,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac } @Override + @Transactional public NpmPackage loadPackage(String thePackageId, String thePackageVersion) throws FHIRException, IOException { NpmPackage cachedPackage = loadPackageFromCacheOnly(thePackageId, thePackageVersion); if (cachedPackage != null) { @@ -414,6 +416,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac } @Override + @Transactional(Transactional.TxType.NEVER) public NpmPackage installPackage(PackageInstallationSpec theInstallationSpec) throws IOException { Validate.notBlank(theInstallationSpec.getName(), "thePackageId must not be blank"); Validate.notBlank(theInstallationSpec.getVersion(), "thePackageVersion must not be blank"); @@ -429,7 +432,13 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac return addPackageToCache(theInstallationSpec.getName(), theInstallationSpec.getVersion(), new ByteArrayInputStream(theInstallationSpec.getPackageContents()), sourceDescription); } - return loadPackage(theInstallationSpec.getName(), theInstallationSpec.getVersion()); + return newTxTemplate().execute(tx -> { + try { + return loadPackage(theInstallationSpec.getName(), theInstallationSpec.getVersion()); + } catch (IOException e) { + throw new InternalErrorException(e); + } + }); } protected byte[] loadPackageUrlContents(String thePackageUrl) { @@ -660,7 +669,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac public List loadPackageAssetsByType(FhirVersionEnum theFhirVersion, String theResourceType) { // List outcome = myPackageVersionResourceDao.findAll(); Slice outcome = myPackageVersionResourceDao.findCurrentVersionByResourceType(PageRequest.of(0, 1000), theFhirVersion, theResourceType); - return outcome.stream().map(t->loadPackageEntity(t)).collect(Collectors.toList()); + return outcome.stream().map(t -> loadPackageEntity(t)).collect(Collectors.toList()); } private void deleteAndExpungeResourceBinary(IIdType theResourceBinaryId, ExpungeOptions theOptions) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index 47f3490806f..2a7f38d1f67 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -968,10 +968,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { // Create an initial search in the DB and give it an ID saveSearch(); - assert !TransactionSynchronizationManager.isActualTransactionActive(); - TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); + txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); if (myCustomIsolationSupported) { txTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java index c39da67e037..9f6b494dd73 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java @@ -1443,6 +1443,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { @Override + @Transactional public boolean isValueSetPreExpandedForCodeValidation(ValueSet theValueSet) { Optional optionalTermValueSet = fetchValueSetEntity(theValueSet); @@ -1471,6 +1472,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { protected IValidationSupport.CodeValidationResult validateCodeIsInPreExpandedValueSet( ConceptValidationOptions theValidationOptions, ValueSet theValueSet, String theSystem, String theCode, String theDisplay, Coding theCoding, CodeableConcept theCodeableConcept) { + assert TransactionSynchronizationManager.isSynchronizationActive(); ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet.hasId(), "ValueSet.id is required"); ResourcePersistentId valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement()); @@ -1538,6 +1540,8 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } private List findByValueSetResourcePidSystemAndCode(ResourcePersistentId theResourcePid, String theSystem, String theCode) { + assert TransactionSynchronizationManager.isSynchronizationActive(); + List retVal = new ArrayList<>(); Optional optionalTermValueSetConcept; int versionIndex = theSystem.indexOf("|"); @@ -1800,6 +1804,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { } @Override + @Transactional public CodeValidationResult validateCode(ConceptValidationOptions theOptions, IIdType theValueSetId, String theValueSetIdentifier, String theCodeSystemIdentifierToValidate, String theCodeToValidate, String theDisplayToValidate, IBaseDatatype theCodingToValidate, IBaseDatatype theCodeableConceptToValidate) { CodeableConcept codeableConcept = toCanonicalCodeableConcept(theCodeableConceptToValidate); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java index 41be4a70a03..e7febcf0848 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java @@ -20,6 +20,7 @@ import org.hl7.fhir.r4.model.ValueSet; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.transaction.Transactional; import java.util.List; import java.util.Optional; import java.util.Set; @@ -103,6 +104,7 @@ public interface ITermReadSvc extends IValidationSupport { /** * Version independent */ + @Transactional() CodeValidationResult validateCodeIsInPreExpandedValueSet(ConceptValidationOptions theOptions, IBaseResource theValueSet, String theSystem, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept); boolean isValueSetPreExpandedForCodeValidation(ValueSet theValueSet); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java index 2aea7021f12..cf3094f4fdd 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java @@ -1214,7 +1214,7 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test { goldenPatient.setId("PAT999"); SystemRequestDetails srd = SystemRequestDetails.newSystemRequestAllPartitions(); DaoMethodOutcome g1Outcome = myPatientDao.update(goldenPatient, srd); - Long goldenPid = myIdHelperService.getPidOrNull(g1Outcome.getResource()); + Long goldenPid = runInTransaction(() -> myIdHelperService.getPidOrNull(g1Outcome.getResource())); //Create our golden records' data. createObservationWithIndex(999, g1Outcome.getId()); @@ -1224,7 +1224,7 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test { for (int i = 0; i < 10; i++) { DaoMethodOutcome patientOutcome = createPatientWithIndex(i); IIdType patId = patientOutcome.getId().toUnqualifiedVersionless(); - Long sourcePid = myIdHelperService.getPidOrNull(patientOutcome.getResource()); + Long sourcePid = runInTransaction(() -> myIdHelperService.getPidOrNull(patientOutcome.getResource())); //Link the patient to the golden resource linkToGoldenResource(goldenPid, sourcePid); @@ -1246,14 +1246,14 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test { Patient goldenPatient2 = new Patient(); goldenPatient2.setId("PAT888"); DaoMethodOutcome g2Outcome = myPatientDao.update(goldenPatient2, new SystemRequestDetails().setRequestPartitionId(RequestPartitionId.defaultPartition())); - Long goldenPid2 = myIdHelperService.getPidOrNull(g2Outcome.getResource()); + Long goldenPid2 = runInTransaction(() -> myIdHelperService.getPidOrNull(g2Outcome.getResource())); //Create some nongroup patients MDM linked to a different golden resource. They shouldnt be included in the query. for (int i = 0; i < 5; i++) { int index = 1000 + i; DaoMethodOutcome patientOutcome = createPatientWithIndex(index); IIdType patId = patientOutcome.getId().toUnqualifiedVersionless(); - Long sourcePid = myIdHelperService.getPidOrNull(patientOutcome.getResource()); + Long sourcePid = runInTransaction(() -> myIdHelperService.getPidOrNull(patientOutcome.getResource())); linkToGoldenResource(goldenPid2, sourcePid); createObservationWithIndex(index, patId); createImmunizationWithIndex(index, patId); @@ -1325,6 +1325,6 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test { mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL); mdmLink.setUpdated(new Date()); mdmLink.setVersion("1"); - myMdmLinkDao.save(mdmLink); + runInTransaction(() -> myMdmLinkDao.save(mdmLink)); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java index 3eeb2fbea3c..26e56711da3 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java @@ -34,6 +34,7 @@ import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; +import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.configuration.JobRegistry; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.launch.NoSuchJobException; @@ -42,6 +43,7 @@ import org.springframework.beans.factory.annotation.Autowired; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static ca.uhn.fhir.jpa.batch.config.BatchConstants.BULK_IMPORT_JOB_NAME; @@ -177,8 +179,14 @@ public class BulkDataImportR4Test extends BaseJpaR4Test implements ITestDataBuil JobInstance jobInstance = myJobExplorer.getLastJobInstance(BULK_IMPORT_JOB_NAME); JobExecution jobExecution = myJobExplorer.getLastJobExecution(jobInstance); - String exitDescription = jobExecution.getExitStatus().getExitDescription(); - assertThat(exitDescription, containsString("File: File With Description")); + List failedExecutions = jobExecution + .getStepExecutions() + .stream() + .filter(t -> t.getExitStatus().getExitCode().equals("FAILED")) + .collect(Collectors.toList()); + + assertEquals(2, failedExecutions.size()); + assertThat(failedExecutions.get(1).getStepName(), containsString(":File With Description")); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/MandatoryTransactionListener.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/MandatoryTransactionListener.java new file mode 100644 index 00000000000..dfd55fa6301 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/MandatoryTransactionListener.java @@ -0,0 +1,26 @@ +package ca.uhn.fhir.jpa.config; + +import net.ttddyy.dsproxy.ExecutionInfo; +import net.ttddyy.dsproxy.QueryInfo; +import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +import java.util.List; +import java.util.Locale; + +public class MandatoryTransactionListener implements ProxyDataSourceBuilder.SingleQueryExecution { + @Override + public void execute(ExecutionInfo execInfo, List queryInfoList) { + if (!TransactionSynchronizationManager.isSynchronizationActive()) { + for (QueryInfo nextQuery : queryInfoList) { + String query = nextQuery.getQuery().toLowerCase(Locale.US); + if (query.contains("hfj_") || query.contains("trm_")) { + if (query.startsWith("select ") || query.startsWith("insert ") || query.startsWith("update ")) { + throw new IllegalStateException("No transaction active executing query: " + nextQuery.getQuery()); + } + } + + } + } + } +} diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestR4Config.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestR4Config.java index 9a480fcc692..2de28dc1dee 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestR4Config.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestR4Config.java @@ -127,6 +127,7 @@ public class TestR4Config extends BaseJavaConfigR4 { // .logQueryBySlf4j(level) .logSlowQueryBySlf4j(10, TimeUnit.SECONDS, level) .beforeQuery(new BlockLargeNumbersOfParamsListener()) + .beforeQuery(new MandatoryTransactionListener()) .afterQuery(captureQueriesListener()) .afterQuery(new CurrentThreadCaptureQueriesListener()) .countQuery(singleQueryCountHolder()) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/ResourceTableFKProviderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/ResourceTableFKProviderTest.java index 3567072c390..8652d823743 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/ResourceTableFKProviderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/ResourceTableFKProviderTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -26,16 +27,18 @@ class ResourceTableFKProviderTest extends BaseJpaR4Test { @Test public void testWeHaveAllForeignKeys() { - List result = myEntityManager.createNativeQuery("SELECT FKTABLE_NAME, FKCOLUMN_NAME FROM INFORMATION_SCHEMA.CROSS_REFERENCES WHERE PKTABLE_NAME = 'HFJ_RESOURCE'").getResultList(); - List expected = result.stream().map(a -> new ResourceForeignKey(a[0].toString(), a[1].toString())).collect(Collectors.toList()); + runInTransaction(()-> { + List result = myEntityManager.createNativeQuery("SELECT FKTABLE_NAME, FKCOLUMN_NAME FROM INFORMATION_SCHEMA.CROSS_REFERENCES WHERE PKTABLE_NAME = 'HFJ_RESOURCE'").getResultList(); + List expected = result.stream().map(a -> new ResourceForeignKey(a[0].toString(), a[1].toString())).collect(Collectors.toList()); - // Add the extra FKs that are not available in the CROSS_REFERENCES table - expected.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID")); - expected.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID")); - expected.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID")); - // If this assertion fails, it means hapi-fhir has added a new foreign-key dependency to HFJ_RESOURCE. To fix - // the test, add the missing key to myResourceTableFKProvider.getResourceForeignKeys() - assertThat(myResourceTableFKProvider.getResourceForeignKeys(), containsInAnyOrder(expected.toArray())); + // Add the extra FKs that are not available in the CROSS_REFERENCES table + expected.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID")); + expected.add(new ResourceForeignKey("TRM_CODESYSTEM_VER", "RES_ID")); + expected.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID")); + // If this assertion fails, it means hapi-fhir has added a new foreign-key dependency to HFJ_RESOURCE. To fix + // the test, add the missing key to myResourceTableFKProvider.getResourceForeignKeys() + assertThat(myResourceTableFKProvider.getResourceForeignKeys(), containsInAnyOrder(expected.toArray())); + }); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java index 8b19feec931..ac307c1c6b5 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java @@ -8,6 +8,7 @@ import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -40,6 +41,11 @@ public class IdHelperServiceTest { @InjectMocks private IdHelperService myHelperService; + @BeforeEach + public void beforeEach() { + myHelperService.setDontCheckActiveTransactionForUnitTest(true); + } + @Test public void resolveResourcePersistentIds_withValidPids_returnsMap() { RequestPartitionId partitionId = RequestPartitionId.allPartitions(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java index 33c86cd934f..ebc36b6000a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java @@ -557,7 +557,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil @AfterEach public void afterPurgeDatabase() { - myMdmLinkDao.deleteAll(); + runInTransaction(()->{ + myMdmLinkDao.deleteAll(); + }); purgeDatabase(myDaoConfig, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataExportSvc); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ComboUniqueParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ComboUniqueParamTest.java index 656781fb8b2..42259ac5218 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ComboUniqueParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ComboUniqueParamTest.java @@ -18,8 +18,22 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.util.HapiExtensions; import org.hl7.fhir.instance.model.api.IIdType; -import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.BooleanType; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Coverage; +import org.hl7.fhir.r4.model.DateTimeType; +import org.hl7.fhir.r4.model.DateType; +import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Enumerations.PublicationStatus; +import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Observation; +import org.hl7.fhir.r4.model.Organization; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.SearchParameter; +import org.hl7.fhir.r4.model.ServiceRequest; import org.junit.jupiter.api.Test; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; @@ -43,8 +57,6 @@ import static org.hamcrest.Matchers.stringContainsInOrder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test { @@ -334,7 +346,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test sp.setType(Enumerations.SearchParamType.COMPOSITE); sp.setStatus(PublicationStatus.ACTIVE); sp.addBase("Patient"); - sp.addComponent() .setExpression("Patient"); + sp.addComponent().setExpression("Patient"); sp.addExtension() .setUrl(HapiExtensions.EXT_SP_UNIQUE) .setValue(new BooleanType(true)); @@ -1103,9 +1115,11 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test public void testUniqueValuesAreIndexed_RefAndDateAndToken() { createUniqueObservationSubjectDateCode(); - List uniques; - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); + runInTransaction(() -> { + List uniques; + uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); Patient pt1 = new Patient(); pt1.setActive(true); @@ -1123,16 +1137,17 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test ourLog.info("ID1: {} - ID2: {} - ID3: {}", id1, id2, id3); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size(), uniques.toString()); - assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size(), uniques.toString()); + assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString()); + }); } @Test public void testUniqueValuesAreIndexed_Reference_UsingModifierSyntax() { createUniqueNameAndManagingOrganizationSps(); - List uniques; Organization org = new Organization(); org.setId("Organization/ORG"); @@ -1149,10 +1164,12 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test assertThat(myMessages.toString(), containsString("Using UNIQUE index for query for search: Patient?name=FAMILY1&organization=Organization%2FORG")); myMessages.clear(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size()); - assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size()); + assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + }); // Again with a change pt1 = new Patient(); @@ -1160,16 +1177,17 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test pt1.addName().setFamily("FAMILY1"); pt1.setManagingOrganization(new Reference("Organization/ORG")); - id1 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization:Organization=ORG", mySrd).getId().toUnqualifiedVersionless(); + IIdType id2 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization:Organization=ORG", mySrd).getId().toUnqualifiedVersionless(); logCapturedMessages(); assertThat(myMessages.toString(), containsString("Using UNIQUE index for query for search: Patient?name=FAMILY1&organization=Organization%2FORG")); myMessages.clear(); - - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size()); - assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size()); + assertEquals("Patient/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + }); } @@ -1208,7 +1226,6 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test @Test public void testUniqueValuesAreIndexed_StringAndReference_UsingConditional() { createUniqueNameAndManagingOrganizationSps(); - List uniques; Organization org = new Organization(); org.setId("Organization/ORG"); @@ -1220,28 +1237,31 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test pt1.setManagingOrganization(new Reference("Organization/ORG")); IIdType id1 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization.name=ORG").getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size()); - assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size()); + assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + }); // Again pt1 = new Patient(); pt1.addName().setFamily("FAMILY1"); pt1.setManagingOrganization(new Reference("Organization/ORG")); - id1 = myPatientDao.update(pt1, "Patient?name=FAMILY1&organization.name=ORG").getId().toUnqualifiedVersionless(); + myPatientDao.update(pt1, "Patient?name=FAMILY1&organization.name=ORG").getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size()); - assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + runInTransaction(()->{ + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size()); + assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + }); } @Test public void testUniqueValuesAreIndexed_StringAndReference_UsingConditionalInTransaction() { createUniqueNameAndManagingOrganizationSps(); - List uniques; Organization org = new Organization(); org.setId("Organization/ORG"); @@ -1251,7 +1271,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test Bundle bundle = new Bundle(); bundle.setType(Bundle.BundleType.TRANSACTION); - String orgId = "urn:uuid:" + UUID.randomUUID().toString(); + String orgId = "urn:uuid:" + UUID.randomUUID(); org = new Organization(); org.setName("ORG"); bundle @@ -1276,10 +1296,12 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test IIdType id1 = new IdType(resp.getEntry().get(1).getResponse().getLocation()); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size()); - assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size()); + assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + }); // Again @@ -1309,13 +1331,14 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test resp = mySystemDao.transaction(mySrd, bundle); - id1 = new IdType(resp.getEntry().get(1).getResponse().getLocation()); - - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size()); - assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + IdType id2 = new IdType(resp.getEntry().get(1).getResponse().getLocation()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size()); + assertEquals("Patient/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Patient?name=FAMILY1&organization=Organization%2FORG", uniques.get(0).getIndexString()); + }); } @Test @@ -1323,26 +1346,31 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test createUniqueBirthdateAndGenderSps(); Patient pt; - List uniques; pt = new Patient(); pt.setGender(Enumerations.AdministrativeGender.MALE); myPatientDao.create(pt).getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); pt = new Patient(); myPatientDao.create(pt).getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); pt = new Patient(); pt.setBirthDateElement(new DateType()); pt.setGender(Enumerations.AdministrativeGender.MALE); myPatientDao.create(pt).getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); } @Test @@ -1354,14 +1382,15 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test org.setName("ORG"); myOrganizationDao.update(org); - List uniques; Patient pt; pt = new Patient(); pt.setManagingOrganization(new Reference("Organization/ORG")); myPatientDao.create(pt).getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); pt = new Patient(); pt.addName() @@ -1370,14 +1399,18 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test .addGiven("GIVEN2") .addGiven("GIVEN2"); // GIVEN2 happens twice myPatientDao.create(pt).getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); - + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); pt = new Patient(); pt.setActive(true); myPatientDao.create(pt).getId().toUnqualifiedVersionless(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(0, uniques.size(), uniques.toString()); + + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(0, uniques.size(), uniques.toString()); + }); } @Test @@ -1402,22 +1435,27 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test myResourceReindexingSvc.forceReindexingPass(); myResourceReindexingSvc.forceReindexingPass(); - List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size(), uniques.toString()); - assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString()); + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size(), uniques.toString()); + assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString()); + }); - myResourceIndexedCompositeStringUniqueDao.deleteAll(); + runInTransaction(() -> { + myResourceIndexedCompositeStringUniqueDao.deleteAll(); + }); myResourceReindexingSvc.markAllResourcesForReindexing(); myResourceReindexingSvc.forceReindexingPass(); myResourceReindexingSvc.forceReindexingPass(); - uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); - assertEquals(1, uniques.size(), uniques.toString()); - assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); - assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString()); - + runInTransaction(() -> { + List uniques = myResourceIndexedCompositeStringUniqueDao.findAll(); + assertEquals(1, uniques.size(), uniques.toString()); + assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue()); + assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString()); + }); } @@ -1509,5 +1547,4 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test } - } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java index 59df75a50d2..fb6ed0ccf65 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java @@ -1212,12 +1212,12 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test { @Test public void testConceptMapFindTermConceptMapByUrl() { - - Pageable page = PageRequest.of(0, 1); - List theExpConceptMapList = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL); - assertEquals(1, theExpConceptMapList.size()); - assertEquals(CM_URL, theExpConceptMapList.get(0).getUrl()); - + runInTransaction(()-> { + Pageable page = PageRequest.of(0, 1); + List theExpConceptMapList = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, CM_URL); + assertEquals(1, theExpConceptMapList.size()); + assertEquals(CM_URL, theExpConceptMapList.get(0).getUrl()); + }); } @Test @@ -1233,24 +1233,26 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test { myConceptMapDao.create(theConceptMap1); myConceptMapDao.create(theConceptMap2); - Optional theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1"); - Optional theExpConceptMapV2 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v2"); + runInTransaction(()-> { + Optional theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1"); + Optional theExpConceptMapV2 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v2"); - assertTrue(theExpConceptMapV1.isPresent()); - assertEquals(theUrl, theExpConceptMapV1.get().getUrl()); - assertEquals("v1", theExpConceptMapV1.get().getVersion()); + assertTrue(theExpConceptMapV1.isPresent()); + assertEquals(theUrl, theExpConceptMapV1.get().getUrl()); + assertEquals("v1", theExpConceptMapV1.get().getVersion()); - assertTrue(theExpConceptMapV2.isPresent()); - assertEquals(theUrl, theExpConceptMapV2.get().getUrl()); - assertEquals("v2", theExpConceptMapV2.get().getVersion()); + assertTrue(theExpConceptMapV2.isPresent()); + assertEquals(theUrl, theExpConceptMapV2.get().getUrl()); + assertEquals("v2", theExpConceptMapV2.get().getVersion()); - // should return the latest one which is v2 - Pageable page = PageRequest.of(0, 1); - List theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl); + // should return the latest one which is v2 + Pageable page = PageRequest.of(0, 1); + List theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl); - assertEquals(1, theExpSecondOne.size()); - assertEquals(theUrl, theExpSecondOne.get(0).getUrl()); - assertEquals("v2", theExpSecondOne.get(0).getVersion()); + assertEquals(1, theExpSecondOne.size()); + assertEquals(theUrl, theExpSecondOne.get(0).getUrl()); + assertEquals("v2", theExpSecondOne.get(0).getVersion()); + }); } @Test @@ -1266,18 +1268,20 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test { myConceptMapDao.create(theConceptMap1); myConceptMapDao.create(theConceptMap2); - Optional theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1"); + runInTransaction(()-> { + Optional theExpConceptMapV1 = myTermConceptMapDao.findTermConceptMapByUrlAndVersion(theUrl, "v1"); - assertTrue(theExpConceptMapV1.isPresent()); - assertEquals(theUrl, theExpConceptMapV1.get().getUrl()); - assertEquals("v1", theExpConceptMapV1.get().getVersion()); + assertTrue(theExpConceptMapV1.isPresent()); + assertEquals(theUrl, theExpConceptMapV1.get().getUrl()); + assertEquals("v1", theExpConceptMapV1.get().getVersion()); - // should return the latest one which is v2 - Pageable page = PageRequest.of(0, 1); - List theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl); + // should return the latest one which is v2 + Pageable page = PageRequest.of(0, 1); + List theExpSecondOne = myTermConceptMapDao.getTermConceptMapEntitiesByUrlOrderByMostRecentUpdate(page, theUrl); - assertEquals(1, theExpSecondOne.size()); - assertEquals(theUrl, theExpSecondOne.get(0).getUrl()); - assertNull(theExpSecondOne.get(0).getVersion()); + assertEquals(1, theExpSecondOne.size()); + assertEquals(theUrl, theExpSecondOne.get(0).getUrl()); + assertNull(theExpSecondOne.get(0).getVersion()); + }); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java index 5c33c51e5ab..9ee4b3bd884 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java @@ -759,7 +759,6 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { } - @Test public void testEmptyChain() { @@ -4923,7 +4922,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { p.addName().setFamily("A1"); myPatientDao.create(p); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(() -> { + assertEquals(0, mySearchEntityDao.count()); + }); SearchParameterMap map = new SearchParameterMap(); StringOrListParam or = new StringOrListParam(); @@ -4934,7 +4935,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); IBundleProvider results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(() -> { + assertEquals(1, mySearchEntityDao.count()); + }); map = new SearchParameterMap(); or = new StringOrListParam(); @@ -4947,7 +4950,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); // We expect a new one because we don't cache the search URL for very long search URLs - assertEquals(2, mySearchEntityDao.count()); + runInTransaction(() -> { + assertEquals(2, mySearchEntityDao.count()); + }); } @Test @@ -5141,7 +5146,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { p.addName().setFamily("A1"); myPatientDao.create(p); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(() -> { + assertEquals(0, mySearchEntityDao.count()); + }); SearchParameterMap map = new SearchParameterMap(); StringOrListParam or = new StringOrListParam(); @@ -5152,8 +5159,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); IBundleProvider results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); - + runInTransaction(() -> { + assertEquals(1, mySearchEntityDao.count()); + }); map = new SearchParameterMap(); or = new StringOrListParam(); or.addOr(new StringParam("A1")); @@ -5163,8 +5171,9 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); - + runInTransaction(() -> { + assertEquals(1, mySearchEntityDao.count()); + }); } /** diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java index 251945e4f61..b1a2d997fe5 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java @@ -89,8 +89,8 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test @AfterEach public void after() { myDaoConfig.setValidateSearchParameterExpressionsOnSave(new DaoConfig().isValidateSearchParameterExpressionsOnSave()); - myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); - } + myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); + } @BeforeEach public void beforeDisableResultReuse() { @@ -101,7 +101,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test @Test public void testStoreSearchParamWithBracketsInExpression() { - + myDaoConfig.setMarkResourcesForReindexingUponSearchParameterChange(true); SearchParameter fooSp = new SearchParameter(); @@ -138,7 +138,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test mySearchParamRegistry.forceRefresh(); } - + @Test public void testStoreSearchParamWithBracketsInExpressionNormalizedQuantityStorageSupported() { @@ -158,7 +158,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test mySearchParameterDao.create(fooSp, mySrd); mySearchParamRegistry.forceRefresh(); } - + /** * See #2023 */ @@ -182,7 +182,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test Patient patient = new Patient(); patient.setId("future-appointment-count-pt"); patient.setActive(true); - patient.addExtension( "http://integer", new IntegerType(1)); + patient.addExtension("http://integer", new IntegerType(1)); myPatientDao.update(patient); IBundleProvider search; @@ -546,7 +546,6 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test } - @Test public void testOverrideAndDisableBuiltInSearchParametersWithOverridingDisabled() { myModelConfig.setDefaultSearchParamsCanBeOverridden(false); @@ -596,13 +595,15 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test g.addMember().getEntity().setReferenceElement(pid); myGroupDao.create(g); - assertThat(myResourceLinkDao.findAll(), empty()); - assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter() { - @Override - public boolean isOut(ResourceIndexedSearchParamToken object) { - return !object.getResourceType().equals("Group") || object.isMissing(); - } - }), empty()); + runInTransaction(() -> { + assertThat(myResourceLinkDao.findAll(), empty()); + assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter() { + @Override + public boolean isOut(ResourceIndexedSearchParamToken object) { + return !object.getResourceType().equals("Group") || object.isMissing(); + } + }), empty()); + }); } /** @@ -1676,7 +1677,4 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test } - - - } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java index f77b6d07025..91e43568dea 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java @@ -84,11 +84,13 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test { org.setActive(true); myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - assertThat(mySearchParamPresentDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1)); - assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty()); + runInTransaction(() -> { + assertThat(mySearchParamPresentDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1)); + assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty()); + }); } @@ -101,11 +103,13 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test { org.setActive(true); myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - assertThat(mySearchParamPresentDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1)); - assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty()); + runInTransaction(() -> { + assertThat(mySearchParamPresentDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1)); + assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty()); + }); } @@ -118,11 +122,13 @@ public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test { org.setActive(true); myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - assertThat(mySearchParamPresentDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1)); - assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty()); + runInTransaction(() -> { + assertThat(mySearchParamPresentDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamDateDao.findAll(), empty()); + assertThat(myResourceIndexedSearchParamTokenDao.findAll(), hasSize(1)); + assertThat(myResourceIndexedSearchParamQuantityDao.findAll(), empty()); + }); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java index 20248bb4f6e..e2dff6b14c3 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java @@ -200,6 +200,28 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { myDaoConfig.setReuseCachedSearchResultsForMillis(null); } + @Test + public void testSearchInExistingTransaction() { + createPatient(withBirthdate("2021-01-01")); + + // Search in a new transaction + IBundleProvider outcome = runInTransaction(() -> { + return myPatientDao.search(new SearchParameterMap().add(Patient.SP_BIRTHDATE, new DateParam("lt2022"))); + }); + assertEquals(1, outcome.sizeOrThrowNpe()); + assertEquals(1, outcome.getResources(0, 999).size()); + + // Search and fetch in a new transaction + runInTransaction(() -> { + IBundleProvider outcome2 = myPatientDao.search(new SearchParameterMap().add(Patient.SP_BIRTHDATE, new DateParam("lt2022"))); + assertEquals(1, outcome2.sizeOrThrowNpe()); + assertEquals(1, outcome2.getResources(0, 999).size()); + }); + + } + + + @Test public void testCanonicalReference() { StructureDefinition sd = new StructureDefinition(); @@ -5079,7 +5101,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { p.addName().setFamily("A1"); myPatientDao.create(p); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); SearchParameterMap map = new SearchParameterMap(); StringOrListParam or = new StringOrListParam(); @@ -5090,7 +5112,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); IBundleProvider results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); map = new SearchParameterMap(); or = new StringOrListParam(); @@ -5103,7 +5125,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); // We expect a new one because we don't cache the search URL for very long search URLs - assertEquals(2, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(2, mySearchEntityDao.count())); } @Test @@ -5296,7 +5318,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { p.addName().setFamily("A1"); myPatientDao.create(p); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); SearchParameterMap map = new SearchParameterMap(); StringOrListParam or = new StringOrListParam(); @@ -5307,7 +5329,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); IBundleProvider results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + assertEquals(1, runInTransaction(()->mySearchEntityDao.count())); map = new SearchParameterMap(); or = new StringOrListParam(); @@ -5318,7 +5340,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + assertEquals(1, runInTransaction(()->mySearchEntityDao.count())); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java index 23a9385d684..71e8ec2341d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java @@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.r4; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.dao.data.ISearchDao; +import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate; @@ -3288,7 +3289,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { p.addName().setFamily("A1"); myPatientDao.create(p); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); SearchParameterMap map = new SearchParameterMap(); StringOrListParam or = new StringOrListParam(); @@ -3299,7 +3300,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); IBundleProvider results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); map = new SearchParameterMap(); or = new StringOrListParam(); @@ -3312,7 +3313,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); // We expect a new one because we don't cache the search URL for very long search URLs - assertEquals(2, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(2, mySearchEntityDao.count())); } @@ -3400,7 +3401,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { p.addName().setFamily("A1"); myPatientDao.create(p); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); SearchParameterMap map = new SearchParameterMap(); StringOrListParam or = new StringOrListParam(); @@ -3411,7 +3412,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); IBundleProvider results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); map = new SearchParameterMap(); or = new StringOrListParam(); @@ -3422,7 +3423,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { map.add(Patient.SP_NAME, or); results = myPatientDao.search(map); assertEquals(1, results.getResources(0, 10).size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java index b88df46c47d..d3a992782a7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java @@ -6,11 +6,11 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum; -import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl; import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParamModifier; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; @@ -18,7 +18,6 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ValidationResult; import org.hl7.fhir.instance.model.api.IIdType; @@ -37,11 +36,10 @@ import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r4.model.ValueSet.FilterOperator; import org.hl7.fhir.r4.model.ValueSet.ValueSetComposeComponent; import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionContainsComponent; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Date; @@ -85,41 +83,43 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); - ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + return runInTransaction(() -> { + ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); - TermCodeSystemVersion cs = new TermCodeSystemVersion(); - cs.setResource(table); + TermCodeSystemVersion cs = new TermCodeSystemVersion(); + cs.setResource(table); - TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); - cs.getConcepts().add(parentA); + TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); + cs.getConcepts().add(parentA); - TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA"); - parentA.addChild(childAA, RelationshipTypeEnum.ISA); + TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA"); + parentA.addChild(childAA, RelationshipTypeEnum.ISA); - TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA"); - childAA.addChild(childAAA, RelationshipTypeEnum.ISA); + TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA"); + childAA.addChild(childAAA, RelationshipTypeEnum.ISA); - TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB"); - childAA.addChild(childAAB, RelationshipTypeEnum.ISA); + TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB"); + childAA.addChild(childAAB, RelationshipTypeEnum.ISA); - TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB"); - parentA.addChild(childAB, RelationshipTypeEnum.ISA); + TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB"); + parentA.addChild(childAB, RelationshipTypeEnum.ISA); - TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); - cs.getConcepts().add(parentB); + TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); + cs.getConcepts().add(parentB); - TermConcept childBA = new TermConcept(cs, "childBA").setDisplay("Child BA"); - childBA.addChild(childAAB, RelationshipTypeEnum.ISA); - parentB.addChild(childBA, RelationshipTypeEnum.ISA); + TermConcept childBA = new TermConcept(cs, "childBA").setDisplay("Child BA"); + childBA.addChild(childAAB, RelationshipTypeEnum.ISA); + parentB.addChild(childBA, RelationshipTypeEnum.ISA); - TermConcept parentC = new TermConcept(cs, "ParentC").setDisplay("Parent C"); - cs.getConcepts().add(parentC); + TermConcept parentC = new TermConcept(cs, "ParentC").setDisplay("Parent C"); + cs.getConcepts().add(parentC); - TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA"); - parentC.addChild(childCA, RelationshipTypeEnum.ISA); + TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA"); + parentC.addChild(childCA, RelationshipTypeEnum.ISA); - myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); - return codeSystem; + myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); + return codeSystem; + }); } private void createExternalCsAndLocalVs() { @@ -135,28 +135,30 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); - ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + return runInTransaction(() -> { + ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); - TermCodeSystemVersion cs = new TermCodeSystemVersion(); - cs.setResource(table); + TermCodeSystemVersion cs = new TermCodeSystemVersion(); + cs.setResource(table); - TermConcept hello = new TermConcept(cs, "hello").setDisplay("Hello"); - cs.getConcepts().add(hello); + TermConcept hello = new TermConcept(cs, "hello").setDisplay("Hello"); + cs.getConcepts().add(hello); - TermConcept goodbye = new TermConcept(cs, "goodbye").setDisplay("Goodbye"); - cs.getConcepts().add(goodbye); + TermConcept goodbye = new TermConcept(cs, "goodbye").setDisplay("Goodbye"); + cs.getConcepts().add(goodbye); - TermConcept dogs = new TermConcept(cs, "dogs").setDisplay("Dogs"); - cs.getConcepts().add(dogs); + TermConcept dogs = new TermConcept(cs, "dogs").setDisplay("Dogs"); + cs.getConcepts().add(dogs); - TermConcept labrador = new TermConcept(cs, "labrador").setDisplay("Labrador"); - dogs.addChild(labrador, RelationshipTypeEnum.ISA); + TermConcept labrador = new TermConcept(cs, "labrador").setDisplay("Labrador"); + dogs.addChild(labrador, RelationshipTypeEnum.ISA); - TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle"); - dogs.addChild(beagle, RelationshipTypeEnum.ISA); + TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle"); + dogs.addChild(beagle, RelationshipTypeEnum.ISA); - myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); - return codeSystem; + myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); + return codeSystem; + }); } private void createExternalCsLarge() { @@ -166,7 +168,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); - ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + ResourceTable table = runInTransaction(()->myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new)); TermCodeSystemVersion cs = new TermCodeSystemVersion(); cs.setResource(table); @@ -331,6 +333,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { assertEquals("Invalid filter, must have fields populated: property op value", e.getMessage()); } } + @Test public void testExpandWithIncludeConceptHaveCodeAndDisplay() { CodeSystem codeSystem = createExternalCsDogs(); @@ -351,7 +354,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { assertEquals(2, result.getExpansion().getTotal()); ArrayList codes = toCodesContains(result.getExpansion().getContains()); assertThat(codes, containsInAnyOrder("hello", "goodbye")); - for (ValueSetExpansionContainsComponent vsConcept : result.getExpansion().getContains()){ + for (ValueSetExpansionContainsComponent vsConcept : result.getExpansion().getContains()) { assertTrue(vsConcept.getDisplay().contains("VS")); } @@ -528,7 +531,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); - ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + ResourceTable table = runInTransaction(()->myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new)); TermCodeSystemVersion cs = new TermCodeSystemVersion(); cs.setResource(table); @@ -549,7 +552,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { concept = new TermConcept(cs, "LA9999-7"); cs.getConcepts().add(concept); - myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table); + myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); ValueSet valueSet = new ValueSet(); valueSet.setUrl(URL_MY_VALUE_SET); @@ -854,13 +857,13 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test { codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); - ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + ResourceTable table = runInTransaction(()->myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalStateException::new)); TermCodeSystemVersion cs = new TermCodeSystemVersion(); cs.setResource(table); TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A"); cs.getConcepts().add(parentA); - myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION" , cs, table); + myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION", cs, table); StringType code = new StringType("ParentA"); StringType system = new StringType("http://snomed.info/sct"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValueSetMultiVersionTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValueSetMultiVersionTest.java index 437e142653b..c6b33820e58 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValueSetMultiVersionTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValueSetMultiVersionTest.java @@ -29,9 +29,6 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test { public static final String URL_MY_VALUE_SET = "http://example.com/my_value_set"; public static final String URL_MY_CODE_SYSTEM = "http://example.com/my_code_system"; - - private enum ValueSetVersions { NULL, V1, V2 } - @Autowired protected ITermValueSetConceptDao myTermValueSetConceptDao; @@ -56,7 +53,7 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test { if (theVersion == null) { valueSet.setName("ValueSet_noVersion"); } else { - valueSet.setName("ValueSet_"+theVersion); + valueSet.setName("ValueSet_" + theVersion); } valueSet.getCompose().addInclude().setSystem(theCodeSystem.getUrl()); return myValueSetDao.create(valueSet, mySrd); @@ -86,31 +83,33 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test { public void testCreateVersionedValueSets() { Map myValueSets = createVersionedValueSets(); - assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + runInTransaction(() -> { + assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); - Optional optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); - assertTrue(optionalTermValueSet.isPresent()); - Long nullVersion_resid = ((ResourceTable)myValueSets.get(ValueSetVersions.NULL).getEntity()).getId(); - assertNotNull(nullVersion_resid); - assertNotNull(optionalTermValueSet.get().getResource()); - assertEquals(nullVersion_resid, optionalTermValueSet.get().getResource().getId()); - assertEquals("ValueSet_noVersion", optionalTermValueSet.get().getName()); + Optional optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); + assertTrue(optionalTermValueSet.isPresent()); + Long nullVersion_resid = ((ResourceTable) myValueSets.get(ValueSetVersions.NULL).getEntity()).getId(); + assertNotNull(nullVersion_resid); + assertNotNull(optionalTermValueSet.get().getResource()); + assertEquals(nullVersion_resid, optionalTermValueSet.get().getResource().getId()); + assertEquals("ValueSet_noVersion", optionalTermValueSet.get().getName()); - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1"); - assertTrue(optionalTermValueSet.isPresent()); - Long v1Version_resid = ((ResourceTable)myValueSets.get(ValueSetVersions.V1).getEntity()).getId(); - assertNotNull(v1Version_resid); - assertNotNull(optionalTermValueSet.get().getResource()); - assertEquals(v1Version_resid, optionalTermValueSet.get().getResource().getId()); - assertEquals("ValueSet_v1", optionalTermValueSet.get().getName()); + optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1"); + assertTrue(optionalTermValueSet.isPresent()); + Long v1Version_resid = ((ResourceTable) myValueSets.get(ValueSetVersions.V1).getEntity()).getId(); + assertNotNull(v1Version_resid); + assertNotNull(optionalTermValueSet.get().getResource()); + assertEquals(v1Version_resid, optionalTermValueSet.get().getResource().getId()); + assertEquals("ValueSet_v1", optionalTermValueSet.get().getName()); - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2"); - assertTrue(optionalTermValueSet.isPresent()); - Long v2Version_resid = ((ResourceTable)myValueSets.get(ValueSetVersions.V2).getEntity()).getId(); - assertNotNull(v2Version_resid); - assertNotNull(optionalTermValueSet.get().getResource()); - assertEquals(v2Version_resid, optionalTermValueSet.get().getResource().getId()); - assertEquals("ValueSet_v2", optionalTermValueSet.get().getName()); + optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2"); + assertTrue(optionalTermValueSet.isPresent()); + Long v2Version_resid = ((ResourceTable) myValueSets.get(ValueSetVersions.V2).getEntity()).getId(); + assertNotNull(v2Version_resid); + assertNotNull(optionalTermValueSet.get().getResource()); + assertEquals(v2Version_resid, optionalTermValueSet.get().getResource().getId()); + assertEquals("ValueSet_v2", optionalTermValueSet.get().getName()); + }); } @@ -118,108 +117,119 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test { public void testUpdateVersionedValueSets() { Map myValueSets = createVersionedValueSets(); - assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + runInTransaction(() -> { + assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); - TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version")); - assertEquals("ValueSet_noVersion", termValueSet.getName()); + TermValueSet vs = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version")); + assertEquals("ValueSet_noVersion", vs.getName()); - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")); - assertEquals("ValueSet_v1", termValueSet.getName()); + vs = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")); + assertEquals("ValueSet_v1", vs.getName()); - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")); - assertEquals("ValueSet_v2", termValueSet.getName()); + vs = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")); + assertEquals("ValueSet_v2", vs.getName()); + }); // Update ValueSets - ValueSet updated = (ValueSet)myValueSets.get(ValueSetVersions.NULL).getResource(); + ValueSet updated = (ValueSet) myValueSets.get(ValueSetVersions.NULL).getResource(); updated.setName("ValueSet_noVersion_updated"); DaoMethodOutcome nullVersion_update_outcome = myValueSetDao.update(updated); - Long nullVersion_resid = ((ResourceTable)nullVersion_update_outcome.getEntity()).getId(); + Long nullVersion_resid = ((ResourceTable) nullVersion_update_outcome.getEntity()).getId(); - updated = (ValueSet)myValueSets.get(ValueSetVersions.V1).getResource(); + updated = (ValueSet) myValueSets.get(ValueSetVersions.V1).getResource(); updated.setName("ValueSet_v1_updated"); DaoMethodOutcome v1Version_update_outcome = myValueSetDao.update(updated); - Long v1Version_resid = ((ResourceTable)v1Version_update_outcome.getEntity()).getId(); + Long v1Version_resid = ((ResourceTable) v1Version_update_outcome.getEntity()).getId(); - updated = (ValueSet)myValueSets.get(ValueSetVersions.V2).getResource(); + updated = (ValueSet) myValueSets.get(ValueSetVersions.V2).getResource(); updated.setName("ValueSet_v2_updated"); DaoMethodOutcome v2Version_update_outcome = myValueSetDao.update(updated); - Long v2Version_resid = ((ResourceTable)v2Version_update_outcome.getEntity()).getId(); + Long v2Version_resid = ((ResourceTable) v2Version_update_outcome.getEntity()).getId(); // Verify that ValueSets were updated. - assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + runInTransaction(() -> assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size())); - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version")); - assertNotNull(nullVersion_resid); - assertNotNull(termValueSet.getResource()); - assertEquals(nullVersion_resid, termValueSet.getResource().getId()); - assertEquals("ValueSet_noVersion_updated", termValueSet.getName()); + runInTransaction(() -> { + TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version")); + assertNotNull(nullVersion_resid); + assertNotNull(termValueSet.getResource()); + assertEquals(nullVersion_resid, termValueSet.getResource().getId()); + assertEquals("ValueSet_noVersion_updated", termValueSet.getName()); - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")); - assertNotNull(v1Version_resid); - assertNotNull(termValueSet.getResource()); - assertEquals(v1Version_resid, termValueSet.getResource().getId()); - assertEquals("ValueSet_v1_updated", termValueSet.getName()); - - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")); - assertNotNull(v2Version_resid); - assertNotNull(termValueSet.getResource()); - assertEquals(v2Version_resid, termValueSet.getResource().getId()); - assertEquals("ValueSet_v2_updated", termValueSet.getName()); + termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")); + assertNotNull(v1Version_resid); + assertNotNull(termValueSet.getResource()); + assertEquals(v1Version_resid, termValueSet.getResource().getId()); + assertEquals("ValueSet_v1_updated", termValueSet.getName()); + termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")); + assertNotNull(v2Version_resid); + assertNotNull(termValueSet.getResource()); + assertEquals(v2Version_resid, termValueSet.getResource().getId()); + assertEquals("ValueSet_v2_updated", termValueSet.getName()); + }); } @Test public void testDeleteVersionedValueSets() { Map myValueSets = createVersionedValueSets(); - assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + runInTransaction(() -> { + assertEquals(3, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); - TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version")); - assertEquals("ValueSet_noVersion", termValueSet.getName()); + TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET).orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " with null version")); + assertEquals("ValueSet_noVersion", termValueSet.getName()); - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")); - assertEquals("ValueSet_v1", termValueSet.getName()); + termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1")); + assertEquals("ValueSet_v1", termValueSet.getName()); - termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")); - assertEquals("ValueSet_v2", termValueSet.getName()); + termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2")); + assertEquals("ValueSet_v2", termValueSet.getName()); + }); // Delete ValueSets myValueSetDao.delete(myValueSets.get(ValueSetVersions.NULL).getResource().getIdElement()); - assertEquals(2, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); - Optional optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); - if (optionalTermValueSet.isPresent()) { - fail(); - } - assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"))); - assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"))); + runInTransaction(() -> { + assertEquals(2, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + Optional optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); + if (optionalTermValueSet.isPresent()) { + fail(); + } + assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v1"))); + assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"))); + }); myValueSetDao.delete(myValueSets.get(ValueSetVersions.V1).getResource().getIdElement()); - assertEquals(1, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); - if (optionalTermValueSet.isPresent()) { - fail(); - } - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1"); - if (optionalTermValueSet.isPresent()) { - fail(); - } - assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"))); + + runInTransaction(() -> { + assertEquals(1, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + Optional optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); + if (optionalTermValueSet.isPresent()) { + fail(); + } + optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1"); + if (optionalTermValueSet.isPresent()) { + fail(); + } + assertNotNull(myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2").orElseThrow(() -> new IllegalArgumentException("No TerValueSet found for " + URL_MY_VALUE_SET + " version v2"))); + }); myValueSetDao.delete(myValueSets.get(ValueSetVersions.V2).getResource().getIdElement()); - assertEquals(0, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); - if (optionalTermValueSet.isPresent()) { - fail(); - } - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1"); - if (optionalTermValueSet.isPresent()) { - fail(); - } - optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2"); - if (optionalTermValueSet.isPresent()) { - fail(); - } - + runInTransaction(() -> { + assertEquals(0, myTermValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 10), URL_MY_VALUE_SET).size()); + Optional optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(URL_MY_VALUE_SET); + if (optionalTermValueSet.isPresent()) { + fail(); + } + optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v1"); + if (optionalTermValueSet.isPresent()) { + fail(); + } + optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(URL_MY_VALUE_SET, "v2"); + if (optionalTermValueSet.isPresent()) { + fail(); + } + }); } @Test @@ -241,6 +251,7 @@ public class FhirResourceDaoR4ValueSetMultiVersionTest extends BaseJpaR4Test { } + private enum ValueSetVersions {NULL, V1, V2} } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java index ef906312341..96546678b70 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSearchDaoR4Test.java @@ -1,30 +1,42 @@ package ca.uhn.fhir.jpa.dao.r4; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; -import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.StringAndListParam; import ca.uhn.fhir.rest.param.StringOrListParam; import ca.uhn.fhir.rest.param.StringParam; -import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.transaction.support.TransactionSynchronizationManager; import java.util.List; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; -import static org.hamcrest.MatcherAssert.assertThat; public class FhirSearchDaoR4Test extends BaseJpaR4Test { @Autowired private IFulltextSearchSvc mySearchDao; - + + @Test + public void testDaoCallRequiresTransaction() { + + try { + myResourceTableDao.count(); + } catch (InvalidDataAccessApiUsageException e) { + // good + } + + assert !TransactionSynchronizationManager.isActualTransactionActive(); + } + @Test public void testContentSearch() { Long id1; @@ -59,7 +71,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS"))); - + map.add(Constants.PARAM_CONTENT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1)); @@ -68,17 +80,17 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB"))); - + map.add(Constants.PARAM_CONTENT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2)); - } + } // AND { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS"))); content.addAnd(new StringOrListParam().addOr(new StringParam("CCC"))); - + map.add(Constants.PARAM_CONTENT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1)); @@ -88,7 +100,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAB")).addOr(new StringParam("AAAS"))); content.addAnd(new StringOrListParam().addOr(new StringParam("CCC"))); - + map.add(Constants.PARAM_CONTENT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2)); @@ -97,14 +109,14 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")).addOr(new StringParam("DDD"))); - + map.add(Constants.PARAM_CONTENT, content); List found = mySearchDao.search(null, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2, id3)); } } - + @Test public void testNarrativeSearch() { Long id1; @@ -132,7 +144,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS"))); - + map.add(Constants.PARAM_TEXT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1)); @@ -141,17 +153,17 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB"))); - + map.add(Constants.PARAM_TEXT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2)); - } + } // AND { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS"))); content.addAnd(new StringOrListParam().addOr(new StringParam("CCC"))); - + map.add(Constants.PARAM_TEXT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1)); @@ -161,7 +173,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("AAAB")).addOr(new StringParam("AAAS"))); content.addAnd(new StringOrListParam().addOr(new StringParam("CCC"))); - + map.add(Constants.PARAM_TEXT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2)); @@ -170,7 +182,7 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test { { StringAndListParam content = new StringAndListParam(); content.addAnd(new StringOrListParam().addOr(new StringParam("div"))); - + map.add(Constants.PARAM_TEXT, content); List found = mySearchDao.search(resourceName, map); assertThat(ResourcePersistentId.toLongList(found), empty()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index 8b9882bc98a..edbb5e46c7d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -3288,8 +3288,8 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { assertThat(e.getMessage(), containsString("Resource type 'Practicioner' is not valid for this path")); } - assertThat(myResourceTableDao.findAll(), empty()); - assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty()); + runInTransaction(()->assertThat(myResourceTableDao.findAll(), empty())); + runInTransaction(()->assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty())); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java index 24bb7903c64..2e929fa5e2b 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java @@ -1780,7 +1780,9 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test { // Date param - ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * "))); + runInTransaction(() -> { + ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * "))); + }); addReadPartition(1); myCaptureQueriesListener.clear(); SearchParameterMap map = new SearchParameterMap(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java index cbd54dca482..3eef98dcd6f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java @@ -66,23 +66,27 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class PersistObservationIndexedSearchParamLastNR4IT { - @Autowired - private ElasticsearchSvcImpl elasticsearchSvc; - - @Autowired - private IFhirSystemDao myDao; - + private final String SINGLE_SUBJECT_ID = "4567"; + private final String SINGLE_OBSERVATION_PID = "123"; + private final Date SINGLE_EFFECTIVEDTM = new Date(); + private final String SINGLE_OBSERVATION_CODE_TEXT = "Test Codeable Concept Field for Code"; + private final String CATEGORYFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-category"; + private final String FIRSTCATEGORYFIRSTCODINGCODE = "test-heart-rate"; + private final String CODEFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-code"; + private final String CODEFIRSTCODINGCODE = "test-code"; @PersistenceContext(type = PersistenceContextType.TRANSACTION) protected EntityManager myEntityManager; - - @Autowired - ObservationLastNIndexPersistSvc testObservationPersist; - @Autowired protected FhirContext myFhirCtx; - + @Autowired + ObservationLastNIndexPersistSvc testObservationPersist; + @Autowired + private ElasticsearchSvcImpl elasticsearchSvc; + @Autowired + private IFhirSystemDao myDao; @Autowired private DaoConfig myDaoConfig; + private ReferenceAndListParam multiSubjectParams = null; @BeforeEach public void before() throws IOException { @@ -100,20 +104,6 @@ public class PersistObservationIndexedSearchParamLastNR4IT { myDaoConfig.setLastNEnabled(new DaoConfig().isLastNEnabled()); } - - private final String SINGLE_SUBJECT_ID = "4567"; - private final String SINGLE_OBSERVATION_PID = "123"; - private final Date SINGLE_EFFECTIVEDTM = new Date(); - private final String SINGLE_OBSERVATION_CODE_TEXT = "Test Codeable Concept Field for Code"; - - private final String CATEGORYFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-category"; - private final String FIRSTCATEGORYFIRSTCODINGCODE = "test-heart-rate"; - - private final String CODEFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-code"; - private final String CODEFIRSTCODINGCODE = "test-code"; - - private ReferenceAndListParam multiSubjectParams = null; - @Order(3) @Test public void testIndexObservationSingle() throws IOException { @@ -467,7 +457,7 @@ public class PersistObservationIndexedSearchParamLastNR4IT { // execute Observation ID search - Composite Aggregation searchParameterMap.setLastNMax(1); - List observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap,myFhirCtx, 200); + List observationIdsOnly = elasticsearchSvc.executeLastN(searchParameterMap, myFhirCtx, 200); assertEquals(20, observationIdsOnly.size()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheTest.java index 1e69896d972..02f285bccd6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheTest.java @@ -150,9 +150,10 @@ public class JpaPackageCacheTest extends BaseJpaR4Test { pkg = myPackageCacheManager.loadPackage("hl7.fhir.us.davinci-cdex", null); assertEquals("0.2.0", pkg.version()); - assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageDao.findByPackageId("hl7.fhir.us.davinci-cdex").get().getDescription()); - assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageVersionDao.findByPackageIdAndVersion("hl7.fhir.us.davinci-cdex", "0.2.0").get().getDescription()); - + runInTransaction(()-> { + assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageDao.findByPackageId("hl7.fhir.us.davinci-cdex").get().getDescription()); + assertEquals("This IG provides detailed guidance that helps implementers use FHIR-based interactions and resources relevant to support specific exchanges of clinical information between provider and payers (or ...", myPackageVersionDao.findByPackageIdAndVersion("hl7.fhir.us.davinci-cdex", "0.2.0").get().getDescription()); + }); } @Test diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ConsentInterceptorResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ConsentInterceptorResourceProviderR4Test.java index d0144436f0e..00384654eff 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ConsentInterceptorResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ConsentInterceptorResourceProviderR4Test.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.UrlUtil; import com.google.common.base.Charsets; -import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import org.apache.commons.collections4.ListUtils; import org.apache.commons.io.IOUtils; @@ -556,7 +555,7 @@ public class ConsentInterceptorResourceProviderR4Test extends BaseResourceProvid myClient.create().resource(new Patient().setGender(Enumerations.AdministrativeGender.MALE).addName(new HumanName().setFamily("2"))).execute(); myClient.create().resource(new Patient().setGender(Enumerations.AdministrativeGender.FEMALE).addName(new HumanName().setFamily("3"))).execute(); - runInTransaction(()->{ + runInTransaction(() -> { assertEquals(3, myResourceTableDao.count()); }); @@ -568,7 +567,7 @@ public class ConsentInterceptorResourceProviderR4Test extends BaseResourceProvid assertNull(response.getTotalElement().getValue()); StopWatch sw = new StopWatch(); - while(true) { + while (true) { SearchStatusEnum status = runInTransaction(() -> { Search search = mySearchEntityDao.findByUuidAndFetchIncludes(searchId).orElseThrow(() -> new IllegalStateException()); return search.getStatus(); @@ -631,7 +630,7 @@ public class ConsentInterceptorResourceProviderR4Test extends BaseResourceProvid await() .until( - ()->mySearchEntityDao.findByUuidAndFetchIncludes(searchId).orElseThrow(() -> new IllegalStateException()).getStatus(), + () -> runInTransaction(() -> mySearchEntityDao.findByUuidAndFetchIncludes(searchId).orElseThrow(() -> new IllegalStateException()).getStatus()), equalTo(SearchStatusEnum.FINISHED) ); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java index 175aa3ff6bc..77b51c90ed9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java @@ -110,8 +110,11 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test { pid.set(resourcePid); }); IIdType savedPatientId = myClient.create().resource(new Patient()).execute().getId(); - Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong(); - assertEquals(savedPatientPid.longValue(), pid.get()); + + runInTransaction(()-> { + Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong(); + assertEquals(savedPatientPid.longValue(), pid.get()); + }); } @Test @@ -124,7 +127,7 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test { pid.set(resourcePid); }); IIdType savedPatientId = myClient.create().resource(new Patient()).execute().getId(); - Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong(); + Long savedPatientPid = runInTransaction(()->myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong()); myClient.delete().resourceById(savedPatientId).execute(); Parameters parameters = new Parameters(); @@ -160,9 +163,11 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test { }); patient.setActive(true); myClient.update().resource(patient).execute(); - Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong(); - assertEquals(savedPatientPid.longValue(), pidOld.get()); - assertEquals(savedPatientPid.longValue(), pidNew.get()); + runInTransaction(()-> { + Long savedPatientPid = myIdHelperService.resolveResourcePersistentIdsWithCache(null, Collections.singletonList(savedPatientId)).get(0).getIdAsLong(); + assertEquals(savedPatientPid.longValue(), pidOld.get()); + assertEquals(savedPatientPid.longValue(), pidNew.get()); + }); } @Test diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java index 0fb63d8147d..abf6b00721d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java @@ -13,11 +13,9 @@ import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.IBundleProvider; -import ca.uhn.fhir.rest.gclient.DateClientParam; import ca.uhn.fhir.rest.gclient.ReferenceClientParam; import ca.uhn.fhir.rest.gclient.StringClientParam; import ca.uhn.fhir.rest.gclient.TokenClientParam; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.util.BundleUtil; import org.apache.commons.io.IOUtils; @@ -222,10 +220,12 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide obs2.setStatus(ObservationStatus.FINAL); IIdType obsId = myObservationDao.create(obs2, mySrd).getId().toUnqualifiedVersionless(); - ResourceTable res = myResourceTableDao.findById(patId.getIdPartAsLong()).orElseThrow(IllegalStateException::new); - assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue()); - res = myResourceTableDao.findById(obsId.getIdPartAsLong()).orElseThrow(IllegalStateException::new); - assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue()); + runInTransaction(() -> { + ResourceTable res = myResourceTableDao.findById(patId.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue()); + res = myResourceTableDao.findById(obsId.getIdPartAsLong()).orElseThrow(IllegalStateException::new); + assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue()); + }); SearchParameter fooSp = new SearchParameter(); fooSp.addBase("Patient"); @@ -459,7 +459,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide .returnBundle(Bundle.class) .execute(); - } catch (Exception e) { + } catch (Exception e) { assertThat(e.getMessage(), is(equalTo("HTTP 400 Bad Request: Invalid date/time format: \"01-01-2020\""))); } @@ -472,7 +472,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide .returnBundle(Bundle.class) .execute(); - } catch (Exception e) { + } catch (Exception e) { assertThat(e.getMessage(), is(equalTo("HTTP 400 Bad Request: Invalid date/time format: \"01-01-2020\""))); } } @@ -586,5 +586,4 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide } - } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java index ba72739616c..28f68e34932 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import java.util.Date; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.blankOrNullString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.greaterThan; @@ -74,7 +75,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { .cacheControl(new CacheControlDirective().setNoStore(true)) .execute(); assertEquals(1, results.getEntry().size()); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); Patient pt2 = new Patient(); @@ -89,7 +90,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { .cacheControl(new CacheControlDirective().setNoStore(true)) .execute(); assertEquals(2, results.getEntry().size()); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); } @@ -111,7 +112,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { .cacheControl(new CacheControlDirective().setNoStore(true).setMaxResults(5)) .execute(); assertEquals(5, results.getEntry().size()); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); } @@ -142,7 +143,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { Bundle results = myClient.search().forResource("Patient").where(Patient.FAMILY.matches().value("FAM")).returnBundle(Bundle.class).execute(); assertEquals(1, results.getEntry().size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(() -> assertEquals(1, mySearchEntityDao.count())); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); Patient pt2 = new Patient(); @@ -157,7 +158,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { .cacheControl(new CacheControlDirective().setNoCache(true)) .execute(); assertEquals(2, results.getEntry().size()); - assertEquals(2, mySearchEntityDao.count()); + runInTransaction(() -> assertEquals(2, mySearchEntityDao.count())); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); } @@ -178,7 +179,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { TestUtil.sleepOneClick(); assertEquals(1, results1.getEntry().size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(() -> assertEquals(1, mySearchEntityDao.count())); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); Date results1Date = TestUtil.getTimestamp(results1).getValue(); assertThat(results1Date, greaterThan(beforeFirst)); @@ -191,7 +192,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { Bundle results2 = myClient.search().forResource("Patient").where(Patient.FAMILY.matches().value("FAM")).returnBundle(Bundle.class).execute(); assertEquals(1, results2.getEntry().size()); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(() -> assertEquals(1, mySearchEntityDao.count())); assertEquals("HIT from " + ourServerBase, myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE).get(0)); assertEquals(results1.getMeta().getLastUpdated(), results2.getMeta().getLastUpdated()); assertEquals(results1.getId(), results2.getId()); @@ -205,7 +206,7 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { p = new Patient(); p.addName().setFamily("Foo"); - String p2Id = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue(); + myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue(); Bundle resp1 = myClient .search() diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java index aa1520dac82..bef399006bb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemTest.java @@ -12,7 +12,15 @@ import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.hl7.fhir.instance.model.api.IIdType; -import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.BooleanType; +import org.hl7.fhir.r4.model.CodeSystem; +import org.hl7.fhir.r4.model.CodeType; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Enumerations; +import org.hl7.fhir.r4.model.Parameters; +import org.hl7.fhir.r4.model.StringType; +import org.hl7.fhir.r4.model.UriType; import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,16 +28,18 @@ import org.springframework.transaction.annotation.Transactional; import java.io.IOException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test { private static final String SYSTEM_PARENTCHILD = "http://parentchild"; private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4CodeSystemTest.class); - private Long parentChildCsId; - - private IIdType myCsId; private static final String CS_ACME_URL = "http://acme.org"; + private Long parentChildCsId; + private IIdType myCsId; @BeforeEach @Transactional @@ -49,14 +59,14 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test parentChildCs.addConcept().setCode("ParentB").setDisplay("Parent B"); DaoMethodOutcome parentChildCsOutcome = myCodeSystemDao.create(parentChildCs); - parentChildCsId = ((ResourceTable)parentChildCsOutcome.getEntity()).getId(); + parentChildCsId = ((ResourceTable) parentChildCsOutcome.getEntity()).getId(); } @Test public void testLookupOnExternalCode() { myCaptureQueriesListener.clear(); - ResourceProviderR4ValueSetNoVerCSNoVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd); + runInTransaction(() -> ResourceProviderR4ValueSetNoVerCSNoVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd)); myCaptureQueriesListener.logAllQueriesForCurrentThread(); Parameters respParam = myClient @@ -531,7 +541,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: Either CodeSystem ID or CodeSystem identifier must be provided. Unable to validate.",e.getMessage()); + assertEquals("HTTP 400 Bad Request: Either CodeSystem ID or CodeSystem identifier must be provided. Unable to validate.", e.getMessage()); } } @@ -561,7 +571,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: No code, coding, or codeableConcept provided to validate.",e.getMessage()); + assertEquals("HTTP 400 Bad Request: No code, coding, or codeableConcept provided to validate.", e.getMessage()); } } @@ -577,7 +587,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: $validate-code can only validate (code) OR (coding) OR (codeableConcept)",e.getMessage()); + assertEquals("HTTP 400 Bad Request: $validate-code can only validate (code) OR (coding) OR (codeableConcept)", e.getMessage()); } } @@ -592,7 +602,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.",e.getMessage()); + assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.", e.getMessage()); } } @@ -641,7 +651,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.",e.getMessage()); + assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.", e.getMessage()); } } @@ -772,7 +782,7 @@ public class ResourceProviderR4CodeSystemTest extends BaseResourceProviderR4Test myClient.operation().onType(CodeSystem.class).named("validate-code").withParameters(inParams).execute(); fail(); } catch (InvalidRequestException e) { - assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.",e.getMessage()); + assertEquals("HTTP 400 Bad Request: Coding.system 'http://url2' does not equal with CodeSystem.url 'http://acme.org'. Unable to validate.", e.getMessage()); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java index bde81bbdc47..f5c04bcdded 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CodeSystemVersionedTest.java @@ -89,8 +89,10 @@ public class ResourceProviderR4CodeSystemVersionedTest extends BaseResourceProvi @Test public void testLookupOnExternalCodeMultiVersion() { - ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "1"); - ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "2"); + runInTransaction(()->{ + ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "1"); + ResourceProviderR4ValueSetVerCSVerTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermCodeSystemStorageSvc, mySrd, "2"); + }); // First test with no version specified (should return from last version created) Parameters respParam = myClient diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetNoVerCSNoVerTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetNoVerCSNoVerTest.java index 9d55c121b3f..42502bfc0c9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetNoVerCSNoVerTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetNoVerCSNoVerTest.java @@ -156,15 +156,17 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv } private void createExternalCsAndLocalVs() { - CodeSystem codeSystem = createExternalCs(); - - createLocalVs(codeSystem); + runInTransaction(() -> { + CodeSystem codeSystem = createExternalCs(); + createLocalVs(codeSystem); + }); } private void createExternalCsAndLocalVsWithUnknownCode() { - CodeSystem codeSystem = createExternalCs(); - - createLocalVsWithUnknownCode(codeSystem); + runInTransaction(() -> { + CodeSystem codeSystem = createExternalCs(); + createLocalVsWithUnknownCode(codeSystem); + }); } private void createLocalCs() { @@ -257,8 +259,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() @@ -312,8 +316,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(() -> { + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() @@ -321,7 +327,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv .named("expand") .withParameter(Parameters.class, "filter", new StringType("blood")) .execute(); - + ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); @@ -338,8 +344,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(() -> { + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() @@ -347,7 +355,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv .named("expand") .withParameter(Parameters.class, "filter", new StringType("blo")) .execute(); - + ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); @@ -355,7 +363,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv assertThat(resp, containsString("")); assertThat(resp, not(containsString("\"Foo Code\""))); } - + @Test public void testExpandByIdWithFilterWithPreExpansionWithoutPrefixValue() throws Exception { myDaoConfig.setPreExpandValueSets(true); @@ -363,7 +371,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + Slice page = runInTransaction(() -> myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED)); assertEquals(1, page.getContent().size()); Parameters respParam = myClient @@ -372,7 +380,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv .named("expand") .withParameter(Parameters.class, "filter", new StringType("lood")) .execute(); - + ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource(); String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); @@ -380,8 +388,8 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv assertThat(resp, not(containsString(""))); assertThat(resp, not(containsString("\"Foo Code\""))); } - - + + @Test public void testExpandByUrl() throws Exception { loadAndPersistCodeSystemAndValueSet(); @@ -446,9 +454,11 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); - myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(()->{ + myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() @@ -799,7 +809,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv */ @Test public void testInvalidFilter() throws Exception { - String string = IOUtils.toString(getClass().getResourceAsStream("/bug_516_invalid_expansion.json"), StandardCharsets.UTF_8); + String string = loadResource("/bug_516_invalid_expansion.json"); HttpPost post = new HttpPost(ourServerBase + "/ValueSet/%24expand"); post.setEntity(new StringEntity(string, ContentType.parse(ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW))); @@ -1080,7 +1090,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion)); assertThat(toDirectCodes(expansion.getExpansion().getContains()), containsInAnyOrder("A")); assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains()), containsInAnyOrder("AA", "AB")); - assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t->t.getCode().equals("AA")).findFirst().orElseThrow(()->new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA")); + assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t -> t.getCode().equals("AA")).findFirst().orElseThrow(() -> new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA")); assertEquals(16, myCaptureQueriesListener.getSelectQueries().size()); } @@ -1120,7 +1130,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion)); assertThat(toDirectCodes(expansion.getExpansion().getContains()), containsInAnyOrder("A")); assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains()), containsInAnyOrder("AA", "AB")); - assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t->t.getCode().equals("AA")).findFirst().orElseThrow(()->new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA")); + assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t -> t.getCode().equals("AA")).findFirst().orElseThrow(() -> new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA")); assertEquals(14, myCaptureQueriesListener.getSelectQueries().size()); } @@ -1172,7 +1182,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion)); assertThat(toDirectCodes(expansion.getExpansion().getContains()), containsInAnyOrder("A")); assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains()), containsInAnyOrder("AA", "AB")); - assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t->t.getCode().equals("AA")).findFirst().orElseThrow(()->new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA")); + assertThat(toDirectCodes(expansion.getExpansion().getContains().get(0).getContains().stream().filter(t -> t.getCode().equals("AA")).findFirst().orElseThrow(() -> new IllegalArgumentException()).getContains()), containsInAnyOrder("AAA")); assertEquals(3, myCaptureQueriesListener.getSelectQueries().size()); } @@ -1435,7 +1445,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv ourLog.info(resp); assertThat(resp, stringContainsInOrder("", "")); } - + @Test public void testExpandByValueSetWithFilterContainsNoPrefixValue() throws IOException { loadAndPersistCodeSystem(); @@ -1453,10 +1463,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - - assertThat(resp, not(stringContainsInOrder("",""))); + + assertThat(resp, not(stringContainsInOrder("", ""))); } - + @Test public void testExpandByValueSetWithFilterNotContainsAnyValue() throws IOException { loadAndPersistCodeSystem(); @@ -1474,10 +1484,10 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded); ourLog.info(resp); - - assertThat(resp, not(stringContainsInOrder("",""))); + + assertThat(resp, not(stringContainsInOrder("", ""))); } - + @Test public void testExpandByUrlWithFilter() throws Exception { loadAndPersistCodeSystemAndValueSet(); @@ -1520,7 +1530,7 @@ public class ResourceProviderR4ValueSetNoVerCSNoVerTest extends BaseResourceProv private boolean clearDeferredStorageQueue() { - if(!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) { + if (!myTerminologyDeferredStorageSvc.isStorageQueueEmpty()) { myTerminologyDeferredStorageSvc.saveAllDeferred(); return false; } else { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java index 811786e9c5a..a9ef0ac1cb5 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSNoVerTest.java @@ -149,15 +149,17 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid } private void createExternalCsAndLocalVs() { - CodeSystem codeSystem = createExternalCs(); - - createLocalVs(codeSystem); + runInTransaction(()-> { + CodeSystem codeSystem = createExternalCs(); + createLocalVs(codeSystem); + }); } private void createExternalCsAndLocalVsWithUnknownCode() { - CodeSystem codeSystem = createExternalCs(); - - createLocalVsWithUnknownCode(codeSystem); + runInTransaction(()-> { + CodeSystem codeSystem = createExternalCs(); + createLocalVsWithUnknownCode(codeSystem); + }); } private void createLocalVs(CodeSystem codeSystem) { @@ -223,8 +225,10 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() @@ -278,8 +282,10 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() @@ -361,8 +367,10 @@ public class ResourceProviderR4ValueSetVerCSNoVerTest extends BaseResourceProvid loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(1, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(1, page.getContent().size()); + }); Parameters respParam = myClient .operation() diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSVerTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSVerTest.java index 8c8708078d2..e9e2300438a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSVerTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ValueSetVerCSVerTest.java @@ -179,14 +179,15 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider } private void createExternalCsAndLocalVs() { - String codeSystemUrl = createExternalCs("1"); - myLocalVs_v1 = createLocalVs(codeSystemUrl, "1"); - myLocalValueSetId_v1 = persistLocalVs(myLocalVs_v1); - - codeSystemUrl = createExternalCs("2"); - myLocalVs_v2 = createLocalVs(codeSystemUrl, "2"); - myLocalValueSetId_v2 = persistLocalVs(myLocalVs_v2); + runInTransaction(()-> { + String codeSystemUrl = createExternalCs("1"); + myLocalVs_v1 = createLocalVs(codeSystemUrl, "1"); + myLocalValueSetId_v1 = persistLocalVs(myLocalVs_v1); + codeSystemUrl = createExternalCs("2"); + myLocalVs_v2 = createLocalVs(codeSystemUrl, "2"); + myLocalValueSetId_v2 = persistLocalVs(myLocalVs_v2); + }); } private ValueSet createLocalVs(String theCodeSystemUrl, String theValueSetVersion) { @@ -268,8 +269,10 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider loadAndPersistCodeSystemAndValueSet(); await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(2, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(2, page.getContent().size()); + }); // Verify v1 ValueSet Parameters respParam = myClient @@ -365,8 +368,10 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(2, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(2, page.getContent().size()); + }); // Validate ValueSet v1 Parameters respParam = myClient @@ -532,8 +537,10 @@ public class ResourceProviderR4ValueSetVerCSVerTest extends BaseResourceProvider await().until(() -> clearDeferredStorageQueue()); myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); - Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); - assertEquals(2, page.getContent().size()); + runInTransaction(()->{ + Slice page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 10), TermValueSetPreExpansionStatusEnum.EXPANDED); + assertEquals(2, page.getContent().size()); + }); // Check expansion of multi-versioned ValueSet with version 1 Parameters respParam = myClient diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java index 9ef68d4c799..1972a386f5a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java @@ -143,11 +143,11 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test { }); // It should take two passes to delete the search fully - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); } @@ -166,10 +166,15 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test { }); // It should take one pass to delete the search fully - assertEquals(1, mySearchEntityDao.count()); - myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()-> { + assertEquals(1, mySearchEntityDao.count()); + }); + myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); + + runInTransaction(()-> { + assertEquals(0, mySearchEntityDao.count()); + }); } @Test @@ -193,15 +198,15 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test { }); // Should not delete right now - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); - assertEquals(1, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(1, mySearchEntityDao.count())); sleepAtLeast(1100); // Now it's time to delete myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); - assertEquals(0, mySearchEntityDao.count()); + runInTransaction(()->assertEquals(0, mySearchEntityDao.count())); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/BaseTermR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/BaseTermR4Test.java index 24441003619..1046267cea6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/BaseTermR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/BaseTermR4Test.java @@ -5,8 +5,8 @@ import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; -import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.model.entity.ResourceTable; +import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.ValueSet; @@ -47,49 +47,51 @@ public abstract class BaseTermR4Test extends BaseJpaR4Test { codeSystem.setVersion("SYSTEM VERSION"); IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); - ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new); + return runInTransaction(() -> { + ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new); - TermCodeSystemVersion cs = new TermCodeSystemVersion(); - cs.setResource(table); + TermCodeSystemVersion cs = new TermCodeSystemVersion(); + cs.setResource(table); - TermConcept parent; - parent = new TermConcept(cs, "ParentWithNoChildrenA"); - cs.getConcepts().add(parent); - parent = new TermConcept(cs, "ParentWithNoChildrenB"); - cs.getConcepts().add(parent); - parent = new TermConcept(cs, "ParentWithNoChildrenC"); - cs.getConcepts().add(parent); + TermConcept parent; + parent = new TermConcept(cs, "ParentWithNoChildrenA"); + cs.getConcepts().add(parent); + parent = new TermConcept(cs, "ParentWithNoChildrenB"); + cs.getConcepts().add(parent); + parent = new TermConcept(cs, "ParentWithNoChildrenC"); + cs.getConcepts().add(parent); - TermConcept parentA = new TermConcept(cs, "ParentA"); - cs.getConcepts().add(parentA); + TermConcept parentA = new TermConcept(cs, "ParentA"); + cs.getConcepts().add(parentA); - TermConcept childAA = new TermConcept(cs, "childAA"); - parentA.addChild(childAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA); + TermConcept childAA = new TermConcept(cs, "childAA"); + parentA.addChild(childAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA); - TermConcept childAAA = new TermConcept(cs, "childAAA"); - childAAA.addPropertyString("propA", "valueAAA"); - childAAA.addPropertyString("propB", "foo"); - childAA.addChild(childAAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA); + TermConcept childAAA = new TermConcept(cs, "childAAA"); + childAAA.addPropertyString("propA", "valueAAA"); + childAAA.addPropertyString("propB", "foo"); + childAA.addChild(childAAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA); - TermConcept childAAB = new TermConcept(cs, "childAAB"); - childAAB.addPropertyString("propA", "valueAAB"); - childAAB.addPropertyString("propB", "foo"); - childAAB.addDesignation() - .setUseSystem("D1S") - .setUseCode("D1C") - .setUseDisplay("D1D") - .setValue("D1V"); - childAA.addChild(childAAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA); + TermConcept childAAB = new TermConcept(cs, "childAAB"); + childAAB.addPropertyString("propA", "valueAAB"); + childAAB.addPropertyString("propB", "foo"); + childAAB.addDesignation() + .setUseSystem("D1S") + .setUseCode("D1C") + .setUseDisplay("D1D") + .setValue("D1V"); + childAA.addChild(childAAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA); - TermConcept childAB = new TermConcept(cs, "childAB"); - parentA.addChild(childAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA); + TermConcept childAB = new TermConcept(cs, "childAB"); + parentA.addChild(childAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA); - TermConcept parentB = new TermConcept(cs, "ParentB"); - cs.getConcepts().add(parentB); + TermConcept parentB = new TermConcept(cs, "ParentB"); + cs.getConcepts().add(parentB); - myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table); + myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table); - return id; + return id; + }); } void loadAndPersistCodeSystemAndValueSet() throws IOException { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcTest.java index 42ace0e1efc..e5b1b6cc27d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcTest.java @@ -11,8 +11,8 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; -import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { @@ -30,7 +30,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { assertEquals(1, myTermCodeSystemVersionDao.count()); TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM); - TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull( myTermCodeSystem.getPid()); + TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid()); assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid()); assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId()); }); @@ -45,14 +45,14 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { CodeSystem duplicateUpload = createCodeSystemWithMoreThan100Concepts(); duplicateUpload.setVersion("1"); - testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 125,"Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"1\", already have one with resource ID: CodeSystem/"); + testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 125, "Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"1\", already have one with resource ID: CodeSystem/"); runInTransaction(() -> { assertEquals(1, myTermCodeSystemDao.count()); assertEquals(1, myTermCodeSystemVersionDao.count()); TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM); - TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion( myTermCodeSystem.getPid(), "1"); + TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "1"); assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid()); assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId()); }); @@ -64,7 +64,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { duplicateUpload = createCodeSystemWithMoreThan100Concepts(); duplicateUpload.setVersion("2"); - testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 251,"Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"2\", already have one with resource ID: CodeSystem/"); + testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 251, "Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"2\", already have one with resource ID: CodeSystem/"); runInTransaction(() -> { assertEquals(1, myTermCodeSystemDao.count()); @@ -103,7 +103,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { theUpload.addConcept(new CodeSystem.ConceptDefinitionComponent(new CodeType("codeB"))); // Update the CodeSystem and CodeSystemVersion entities runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(theUpload, codeSystemResourceEntity)); - validateCodeSystemUpdates(expectedCnt+1); + validateCodeSystemUpdates(expectedCnt + 1); // Try duplicating the CodeSystem Long originalResId = codeSystemResourceEntity.getId(); @@ -118,7 +118,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { theUpload.setConcept(new ArrayList<>()); theUpload.setContent((CodeSystem.CodeSystemContentMode.NOTPRESENT)); runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(theUpload, codeSystemResourceEntity)); - validateCodeSystemUpdates(expectedCnt+1); + validateCodeSystemUpdates(expectedCnt + 1); } @@ -126,7 +126,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test { myTerminologyDeferredStorageSvc.setProcessDeferred(true); myTerminologyDeferredStorageSvc.saveDeferred(); myTerminologyDeferredStorageSvc.setProcessDeferred(false); - assertEquals(theExpectedConceptCount, myTermConceptDao.count()); + assertEquals(theExpectedConceptCount, runInTransaction(() -> myTermConceptDao.count())); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java index 94382a7ff0c..90fa4501bca 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplCurrentVersionR4Test.java @@ -267,6 +267,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { private void validateExpandedTermConcepts(String theCurrentVersion, Collection theAllVersions) { + runInTransaction(() -> { TermConcept termConceptNoVerCsvNoVer = (TermConcept) myEntityManager.createQuery( "select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" + VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult(); @@ -297,8 +298,9 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvVer.getDisplay()); } - theAllVersions.forEach(this::validateExpandedTermConceptsForVersion); + + }); } @@ -474,17 +476,21 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { assertNull(vs.getVersion()); // current TermVSs with no upload version have null version - Optional noUploadCurrentVsOpt = myITermReadSvc.findCurrentTermValueSet(VS_NO_VERSIONED_ON_UPLOAD); + Optional noUploadCurrentVsOpt = getCurrentTermValueSet(VS_NO_VERSIONED_ON_UPLOAD); assertTrue(noUploadCurrentVsOpt.isPresent()); assertNull(noUploadCurrentVsOpt.get().getVersion()); // current VSs with upload version have upload-version with no version append - Optional uploadCurrentVsOpt = myITermReadSvc.findCurrentTermValueSet(VS_VERSIONED_ON_UPLOAD); + Optional uploadCurrentVsOpt = getCurrentTermValueSet(VS_VERSIONED_ON_UPLOAD); assertTrue(uploadCurrentVsOpt.isPresent()); assertEquals(VS_ANSWER_LIST_VERSION, uploadCurrentVsOpt.get().getVersion()); } + private Optional getCurrentTermValueSet(String theTheVsNoVersionedOnUpload) { + return runInTransaction(() -> myITermReadSvc.findCurrentTermValueSet(theTheVsNoVersionedOnUpload)); + } + @Test() public void uploadCurrentNoVersion() throws Exception { @@ -515,7 +521,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { } - @Test public void uploadNoVersionThenNoCurrent() throws Exception { uploadLoincCodeSystem(null, true); @@ -649,38 +654,12 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { } - /** - * Validates TermConcepts were created in the sequence indicated by the parameters - * and their displays match the expected versions - */ - private void validateTermConceptsLoincAllVs(ArrayList theExpectedVersions) { - @SuppressWarnings("unchecked") - List termConceptNoVerList = (List) myEntityManager.createQuery( - "from TermConcept where myCode = '" + VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' order by myId").getResultList(); - assertEquals(theExpectedVersions.size(), termConceptNoVerList.size()); - for (int i = 0; i < theExpectedVersions.size(); i++) { - assertEquals( prefixWithVersion(theExpectedVersions.get(i), VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), - termConceptNoVerList.get(i).getDisplay(), "TermCode with id: " + i + " display"); - } - - @SuppressWarnings("unchecked") - List termConceptWithVerList = (List) myEntityManager.createQuery( - "from TermConcept where myCode = '" + VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' order by myId").getResultList(); - assertEquals(theExpectedVersions.size(), termConceptWithVerList.size()); - for (int i = 0; i < theExpectedVersions.size(); i++) { - assertEquals( prefixWithVersion(theExpectedVersions.get(i), VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), - termConceptWithVerList.get(i).getDisplay(), "TermCode with id: " + i + " display"); - } - } - - - - /** * Validates TermConcepts were created in the sequence indicated by the parameters * and their displays match the expected versions */ private void validateTermConcepts(ArrayList theExpectedVersions) { + runInTransaction(() -> { @SuppressWarnings("unchecked") List termConceptNoVerList = (List) myEntityManager.createQuery( "from TermConcept where myCode = '" + VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' order by myId").getResultList(); @@ -698,6 +677,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { assertEquals( prefixWithVersion(theExpectedVersions.get(i), VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptWithVerList.get(i).getDisplay(), "TermCode with id: " + i + " display"); } + }); } @@ -742,8 +722,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { } - - private IIdType uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception { myFiles = new ZipCollectionBuilder(); @@ -784,15 +762,23 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { if (StringUtils.isBlank(theVersion)) return theClassPathPrefix; switch(theVersion) { - case "2.67": return "/loinc-ver/v267/"; - case "2.68": return "/loinc-ver/v268/"; - case "2.69": return "/loinc-ver/v269/"; + case "2.67": + return "/loinc-ver/v267/"; + case "2.68": + return "/loinc-ver/v268/"; + case "2.69": + return "/loinc-ver/v269/"; } fail("Setup failed. Unexpected version: " + theVersion); return null; } + private TermCodeSystemVersion fetchCurrentCodeSystemVersion() { + return runInTransaction(() -> (TermCodeSystemVersion) myEntityManager.createQuery( + "select tcsv from TermCodeSystemVersion tcsv join fetch tcsv.myCodeSystem tcs " + + "where tcs.myCurrentVersion = tcsv").getSingleResult()); + } private static void addBaseLoincMandatoryFilesToZip( ZipCollectionBuilder theFiles, Boolean theIncludeTop2000, String theClassPathPrefix) throws IOException { @@ -820,11 +806,5 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test { } } - private TermCodeSystemVersion fetchCurrentCodeSystemVersion() { - return (TermCodeSystemVersion) myEntityManager.createQuery( - "select tcsv from TermCodeSystemVersion tcsv join fetch tcsv.myCodeSystem tcs " + - "where tcs.myCurrentVersion = tcsv" ).getSingleResult(); - } - } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java index 40aae7b0c75..4b0f0d73ef9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java @@ -130,12 +130,16 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test { ValueSet expandedValueSet = myTermSvc.expandValueSet(null, valueSet); ourLog.info("Expanded ValueSet:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expandedValueSet)); - TermValueSet termValueSet = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get(); + TermValueSet termValueSet = runInTransaction(()-> { + TermValueSet vs = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get(); + Long termValueSetId = vs.getId(); + assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(termValueSetId).intValue()); + assertEquals(3, vs.getTotalConceptDesignations().intValue()); + assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(termValueSetId).intValue()); + assertEquals(24, vs.getTotalConcepts().intValue()); + return vs; + }); Long termValueSetId = termValueSet.getId(); - assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(termValueSetId).intValue()); - assertEquals(3, termValueSet.getTotalConceptDesignations().intValue()); - assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(termValueSetId).intValue()); - assertEquals(24, termValueSet.getTotalConcepts().intValue()); new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() { @Override @@ -167,12 +171,15 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test { ValueSet expandedValueSet = myTermSvc.expandValueSet(null, valueSet); ourLog.info("Expanded ValueSet:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expandedValueSet)); - TermValueSet termValueSet = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get(); - Long termValueSetId = termValueSet.getId(); - assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(termValueSetId).intValue()); - assertEquals(3, termValueSet.getTotalConceptDesignations().intValue()); - assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(termValueSetId).intValue()); - assertEquals(24, termValueSet.getTotalConcepts().intValue()); + Long termValueSetId = runInTransaction(()-> { + TermValueSet termValueSet = myTermValueSetDao.findByResourcePid(myExtensionalVsIdOnResourceTable).get(); + Long id = termValueSet.getId(); + assertEquals(3, myTermValueSetConceptDesignationDao.countByTermValueSetId(id).intValue()); + assertEquals(3, termValueSet.getTotalConceptDesignations().intValue()); + assertEquals(24, myTermValueSetConceptDao.countByTermValueSetId(id).intValue()); + assertEquals(24, termValueSet.getTotalConcepts().intValue()); + return id; + }); new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() { @Override diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvc.java index 8f72e867bc7..e8b5845d205 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvc.java @@ -129,6 +129,7 @@ public class MdmLinkDaoSvc { * @param theSourcePid The Pid of the source you wish to find the matching link for. * @return the {@link MdmLink} that contains the Match information for the source. */ + @Transactional public Optional getMatchedLinkForSourcePid(Long theSourcePid) { MdmLink exampleLink = myMdmLinkFactory.newMdmLink(); exampleLink.setSourcePid(theSourcePid); @@ -187,6 +188,7 @@ public class MdmLinkDaoSvc { return myMdmLinkDao.findAll(example); } + @Transactional public Optional findMdmLinkBySource(IBaseResource theSourceResource) { @Nullable Long pid = myIdHelperService.getPidOrNull(theSourceResource); if (pid == null) { @@ -214,6 +216,7 @@ public class MdmLinkDaoSvc { * @param theGoldenResource The {@link IBaseResource} Golden Resource who's links you would like to retrieve. * @return A list of all {@link MdmLink} entities in which theGoldenResource is the source Golden Resource */ + @Transactional public List findMdmLinksByGoldenResource(IBaseResource theGoldenResource) { Long pid = myIdHelperService.getPidOrNull(theGoldenResource); if (pid == null) { @@ -256,6 +259,7 @@ public class MdmLinkDaoSvc { * @param theSourceResource the source resource to find links for. * @return all links for the source. */ + @Transactional public List findMdmLinksBySourceResource(IBaseResource theSourceResource) { Long pid = myIdHelperService.getPidOrNull(theSourceResource); if (pid == null) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java index 996dbe8e5cc..460dd7b08eb 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java @@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; +import org.springframework.transaction.annotation.Transactional; public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc { @@ -50,6 +51,7 @@ public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc { IMdmModelConverterSvc myMdmModelConverterSvc; @Override + @Transactional public Page queryLinks(IIdType theGoldenResourceId, IIdType theSourceResourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) { Example exampleLink = exampleLinkFromParameters(theGoldenResourceId, theSourceResourceId, theMatchResult, theLinkSource); Page mdmLinkByExample = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest); @@ -58,6 +60,7 @@ public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc { } @Override + @Transactional public Page getDuplicateGoldenResources(MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) { Example exampleLink = exampleLinkFromParameters(null, null, MdmMatchResultEnum.POSSIBLE_DUPLICATE, null); Page mdmLinkPage = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchFinderSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchFinderSvcImpl.java index 98cbcbae2d6..130375eeaef 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchFinderSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchFinderSvcImpl.java @@ -31,6 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Nonnull; +import javax.transaction.Transactional; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -47,6 +48,7 @@ public class MdmMatchFinderSvcImpl implements IMdmMatchFinderSvc { @Override @Nonnull + @Transactional public List getMatchedTargets(String theResourceType, IAnyResource theResource) { Collection targetCandidates = myMdmCandidateSearchSvc.findCandidates(theResourceType, theResource); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index 8eda5742dd2..5f3e65f6a37 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -36,6 +36,7 @@ import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.transaction.Transactional; import java.util.ArrayList; import java.util.List; @@ -67,6 +68,7 @@ public class MdmMatchLinkSvc { * @param theMdmTransactionContext * @return an {@link TransactionLogMessages} which contains all informational messages related to MDM processing of this resource. */ + @Transactional public MdmTransactionContext updateMdmLinksForMdmSource(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) { if (MdmResourceUtil.isMdmAllowed(theResource)) { return doMdmUpdate(theResource, theMdmTransactionContext); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmCandidateSearchSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmCandidateSearchSvc.java index 11ea12c1c5a..5dc681c8ca9 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmCandidateSearchSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmCandidateSearchSvc.java @@ -31,6 +31,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.Collections; @@ -68,6 +69,7 @@ public class MdmCandidateSearchSvc { * * @return the list of candidate {@link IBaseResource} which could be matches to theResource */ + @Transactional public Collection findCandidates(String theResourceType, IAnyResource theResource) { Map matchedPidsToResources = new HashMap<>(); List filterSearchParams = myMdmSettings.getMdmRules().getCandidateFilterSearchParams(); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java index 6ef1ccb6284..0762dab8412 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java @@ -1,9 +1,7 @@ package ca.uhn.fhir.jpa.mdm; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.api.AddProfileTagEnum; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; -import ca.uhn.fhir.interceptor.api.IInterceptorService; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; @@ -34,21 +32,12 @@ import ca.uhn.fhir.mdm.rules.svc.MdmResourceMatcherSvc; import ca.uhn.fhir.mdm.util.EIDHelper; import ca.uhn.fhir.mdm.util.MdmResourceUtil; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; -import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.server.IBundleProvider; -import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.TokenParam; -import ca.uhn.fhir.rest.server.BasePagingProvider; -import ca.uhn.fhir.rest.server.ETagSupportEnum; -import ca.uhn.fhir.rest.server.ElementsSupportEnum; -import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; -import ca.uhn.fhir.rest.server.IPagingProvider; -import ca.uhn.fhir.rest.server.IRestfulServerDefaults; -import ca.uhn.fhir.rest.server.RestfulServer; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import org.apache.commons.lang3.StringUtils; +import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -61,14 +50,11 @@ import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Reference; -import javax.annotation.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -79,6 +65,7 @@ import java.util.Date; import java.util.List; import java.util.Optional; import java.util.function.Function; +import java.util.function.Supplier; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.slf4j.LoggerFactory.getLogger; @@ -88,21 +75,19 @@ import static org.slf4j.LoggerFactory.getLogger; abstract public class BaseMdmR4Test extends BaseJpaR4Test { - private static final Logger ourLog = getLogger(BaseMdmR4Test.class); - public static final String NAME_GIVEN_JANE = "Jane"; public static final String NAME_GIVEN_PAUL = "Paul"; public static final String TEST_NAME_FAMILY = "Doe"; protected static final String TEST_ID_SYSTEM = "http://a.tv/"; protected static final String JANE_ID = "ID.JANE.123"; protected static final String PAUL_ID = "ID.PAUL.456"; + protected static final String FRANK_ID = "ID.FRANK.789"; + protected static final String DUMMY_ORG_ID = "Organization/mfr"; + private static final Logger ourLog = getLogger(BaseMdmR4Test.class); private static final ContactPoint TEST_TELECOM = new ContactPoint() .setSystem(ContactPoint.ContactPointSystem.PHONE) .setValue("555-555-5555"); private static final String NAME_GIVEN_FRANK = "Frank"; - protected static final String FRANK_ID = "ID.FRANK.789"; - protected static final String DUMMY_ORG_ID = "Organization/mfr"; - @Autowired protected FhirContext myFhirContext; @Autowired @@ -129,13 +114,11 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { protected MdmMatchLinkSvc myMdmMatchLinkSvc; @Autowired protected EIDHelper myEIDHelper; + protected ServletRequestDetails myRequestDetails; @Autowired SearchParamRegistryImpl mySearchParamRegistry; @Autowired private IInterceptorBroadcaster myInterceptorBroadcaster; - - protected ServletRequestDetails myRequestDetails; - @Autowired private DaoRegistry myDaoRegistry; @@ -170,7 +153,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { protected Patient createGoldenPatient(Patient thePatient) { return createPatient(thePatient, true, false); } - + @Nonnull protected Patient createRedirectedGoldenPatient(Patient thePatient) { return createPatient(thePatient, true, true); @@ -329,7 +312,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { String resourceType = theBaseResource.getIdElement().getResourceType(); IFhirResourceDao relevantDao = myDaoRegistry.getResourceDao(resourceType); - Optional matchedLinkForTargetPid = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(theBaseResource)); + Optional matchedLinkForTargetPid = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(runInTransaction(()->myIdHelperService.getPidOrNull(theBaseResource))); if (matchedLinkForTargetPid.isPresent()) { Long goldenResourcePid = matchedLinkForTargetPid.get().getGoldenResourcePid(); return (T) relevantDao.readByPid(new ResourcePersistentId(goldenResourcePid)); @@ -408,28 +391,52 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { return thePractitioner; } + private Matcher wrapMatcherInTransaction(Supplier> theFunction) { + return new Matcher() { + @Override + public boolean matches(Object actual) { + return runInTransaction(()->theFunction.get().matches(actual)); + } + + @Override + public void describeMismatch(Object actual, Description mismatchDescription) { + runInTransaction(()->theFunction.get().describeMismatch(actual, mismatchDescription)); + } + + @Override + public void _dont_implement_Matcher___instead_extend_BaseMatcher_() { + + } + + @Override + public void describeTo(Description description) { + runInTransaction(()->theFunction.get().describeTo(description)); + } + }; + } + protected Matcher sameGoldenResourceAs(IAnyResource... theBaseResource) { - return IsSameGoldenResourceAs.sameGoldenResourceAs(myIdHelperService, myMdmLinkDaoSvc, theBaseResource); + return wrapMatcherInTransaction(()->IsSameGoldenResourceAs.sameGoldenResourceAs(myIdHelperService, myMdmLinkDaoSvc, theBaseResource)); } protected Matcher linkedTo(IAnyResource... theBaseResource) { - return IsLinkedTo.linkedTo(myIdHelperService, myMdmLinkDaoSvc, theBaseResource); + return wrapMatcherInTransaction(()->IsLinkedTo.linkedTo(myIdHelperService, myMdmLinkDaoSvc, theBaseResource)); } protected Matcher possibleLinkedTo(IAnyResource... theBaseResource) { - return IsPossibleLinkedTo.possibleLinkedTo(myIdHelperService, myMdmLinkDaoSvc, theBaseResource); + return wrapMatcherInTransaction(()->IsPossibleLinkedTo.possibleLinkedTo(myIdHelperService, myMdmLinkDaoSvc, theBaseResource)); } protected Matcher possibleMatchWith(IAnyResource... theBaseResource) { - return IsPossibleMatchWith.possibleMatchWith(myIdHelperService, myMdmLinkDaoSvc, theBaseResource); + return wrapMatcherInTransaction(()->IsPossibleMatchWith.possibleMatchWith(myIdHelperService, myMdmLinkDaoSvc, theBaseResource)); } protected Matcher possibleDuplicateOf(IAnyResource... theBaseResource) { - return IsPossibleDuplicateOf.possibleDuplicateOf(myIdHelperService, myMdmLinkDaoSvc, theBaseResource); + return wrapMatcherInTransaction(()->IsPossibleDuplicateOf.possibleDuplicateOf(myIdHelperService, myMdmLinkDaoSvc, theBaseResource)); } protected Matcher matchedToAGoldenResource() { - return IsMatchedToAGoldenResource.matchedToAGoldenResource(myIdHelperService, myMdmLinkDaoSvc); + return wrapMatcherInTransaction(()->IsMatchedToAGoldenResource.matchedToAGoldenResource(myIdHelperService, myMdmLinkDaoSvc)); } protected Patient getOnlyGoldenPatient() { @@ -468,8 +475,8 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { MdmLink mdmLink = myMdmLinkDaoSvc.newMdmLink(); mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL); mdmLink.setMatchResult(MdmMatchResultEnum.MATCH); - mdmLink.setGoldenResourcePid(myIdHelperService.getPidOrNull(sourcePatient)); - mdmLink.setSourcePid(myIdHelperService.getPidOrNull(patient)); + mdmLink.setGoldenResourcePid(runInTransaction(() -> myIdHelperService.getPidOrNull(sourcePatient))); + mdmLink.setSourcePid(runInTransaction(() -> myIdHelperService.getPidOrNull(patient))); return mdmLink; } @@ -497,6 +504,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { protected void assertLinksMatchedByEid(Boolean... theExpectedValues) { assertFields(MdmLink::getEidMatch, theExpectedValues); } + public SearchParameterMap buildGoldenResourceSearchParameterMap() { SearchParameterMap spMap = new SearchParameterMap(); spMap.setLoadSynchronous(true); @@ -513,7 +521,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { } - protected void print(String message, IBaseResource ... theResource) { + protected void print(String message, IBaseResource... theResource) { if (StringUtils.isNotEmpty(message)) { ourLog.info(message); } @@ -523,21 +531,11 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { } } - protected void print(IBaseResource ... theResource) { + protected void print(IBaseResource... theResource) { print(null, theResource); } - - protected void printResources(String theResourceType) { - IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResourceType); - IBundleProvider search = dao.search(new SearchParameterMap()); - search.getResources(0, search.size()).forEach(r -> { - print(r); - }); - } - - protected void printLinks() { myMdmLinkDao.findAll().forEach(mdmLink -> { ourLog.info(String.valueOf(mdmLink)); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java index ae034af6fa7..559c1cb542d 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java @@ -99,7 +99,7 @@ public class MdmLinkDaoSvcTest extends BaseMdmR4Test { mdmLink.setCreated(new Date()); mdmLink.setUpdated(new Date()); mdmLink.setGoldenResourcePid(thePatientPid); - mdmLink.setSourcePid(myIdHelperService.getPidOrNull(patient)); + mdmLink.setSourcePid(runInTransaction(()->myIdHelperService.getPidOrNull(patient))); MdmLink saved= myMdmLinkDao.save(mdmLink); return saved; } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index 4509b9052da..dd4b3db3a64 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -210,7 +210,7 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { patient.setId(patientId); // Updating a Golden Resource Patient who was created via MDM should fail. - MdmLink mdmLink = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(patient)).get(); + MdmLink mdmLink = runInTransaction(()->myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(patient)).orElseThrow(()->new IllegalStateException())); Long sourcePatientPid = mdmLink.getGoldenResourcePid(); Patient goldenResourcePatient = myPatientDao.readByPid(new ResourcePersistentId(sourcePatientPid)); goldenResourcePatient.setGender(Enumerations.AdministrativeGender.MALE); @@ -244,7 +244,11 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { jane = addExternalEID(jane, "some_new_eid"); MdmHelperR4.OutcomeAndLogMessageWrapper outcomeWrapper = myMdmHelper.updateWithLatch(jane); + + IAnyResource patient = getGoldenResourceFromTargetResource(jane); + + List externalEids = myEIDHelper.getExternalEid(patient); assertThat(externalEids, hasSize(1)); assertThat("some_new_eid", is(equalTo(externalEids.get(0).getValue()))); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderBatchR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderBatchR4Test.java index db593713c0c..0e59c6e5e7f 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderBatchR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderBatchR4Test.java @@ -39,6 +39,7 @@ public class MdmProviderBatchR4Test extends BaseLinkR4Test { IInterceptorService myInterceptorService; PointcutLatch afterMdmLatch = new PointcutLatch(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED); + @Override @BeforeEach public void before() { super.before(); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderQueryLinkR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderQueryLinkR4Test.java index dc72acce1d5..e84b8a3b1d9 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderQueryLinkR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderQueryLinkR4Test.java @@ -57,10 +57,10 @@ public class MdmProviderQueryLinkR4Test extends BaseLinkR4Test { myLinkSource = new StringType(MdmLinkSourceEnum.AUTO.name()); Patient sourcePatient1 = createGoldenPatient(); myGoldenResource1Id = new StringType(sourcePatient1.getIdElement().toVersionless().getValue()); - Long sourcePatient1Pid = myIdHelperService.getPidOrNull(sourcePatient1); + Long sourcePatient1Pid = runInTransaction(()->myIdHelperService.getPidOrNull(sourcePatient1)); Patient sourcePatient2 = createGoldenPatient(); myGoldenResource2Id = new StringType(sourcePatient2.getIdElement().toVersionless().getValue()); - Long sourcePatient2Pid = myIdHelperService.getPidOrNull(sourcePatient2); + Long sourcePatient2Pid = runInTransaction(()->myIdHelperService.getPidOrNull(sourcePatient2)); MdmLink possibleDuplicateMdmLink = myMdmLinkDaoSvc.newMdmLink().setGoldenResourcePid(sourcePatient1Pid).setSourcePid(sourcePatient2Pid).setMatchResult(MdmMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(MdmLinkSourceEnum.AUTO); saveLink(possibleDuplicateMdmLink); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmCandidateSearchSvcIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmCandidateSearchSvcIT.java index 3d9e7f2b6d3..318c427a365 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmCandidateSearchSvcIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmCandidateSearchSvcIT.java @@ -82,9 +82,9 @@ public class MdmCandidateSearchSvcIT extends BaseMdmR4Test { Patient newJane = buildJanePatient(); createActivePatient(); - assertEquals(1, myMdmCandidateSearchSvc.findCandidates("Patient", newJane).size()); + assertEquals(1, runInTransaction(()->myMdmCandidateSearchSvc.findCandidates("Patient", newJane).size())); createActivePatient(); - assertEquals(2, myMdmCandidateSearchSvc.findCandidates("Patient", newJane).size()); + assertEquals(2, runInTransaction(()->myMdmCandidateSearchSvc.findCandidates("Patient", newJane).size())); try { createActivePatient(); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmGoldenResourceMergerSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmGoldenResourceMergerSvcTest.java index 5fc6609f9d2..b1971b437de 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmGoldenResourceMergerSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmGoldenResourceMergerSvcTest.java @@ -66,10 +66,10 @@ public class MdmGoldenResourceMergerSvcTest extends BaseMdmR4Test { public void before() { myFromGoldenPatient = createGoldenPatient(); IdType fromSourcePatientId = myFromGoldenPatient.getIdElement().toUnqualifiedVersionless(); - myFromGoldenPatientPid = myIdHelperService.getPidOrThrowException(fromSourcePatientId); + myFromGoldenPatientPid = runInTransaction(()->myIdHelperService.getPidOrThrowException(fromSourcePatientId)); myToGoldenPatient = createGoldenPatient(); IdType toGoldenPatientId = myToGoldenPatient.getIdElement().toUnqualifiedVersionless(); - myToGoldenPatientPid = myIdHelperService.getPidOrThrowException(toGoldenPatientId); + myToGoldenPatientPid = runInTransaction(()->myIdHelperService.getPidOrThrowException(toGoldenPatientId)); myTargetPatient1 = createPatient(); myTargetPatient2 = createPatient(); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java index e1cef8a2400..8340e73b615 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcTest.java @@ -81,8 +81,8 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { Patient goldenPatient1 = createGoldenPatient(); Patient goldenPatient2 = createGoldenPatient(); - Long goldenPatient1Pid = myIdHelperService.getPidOrNull(goldenPatient1); - Long goldenPatient2Pid = myIdHelperService.getPidOrNull(goldenPatient2); + Long goldenPatient1Pid = runInTransaction(()->myIdHelperService.getPidOrNull(goldenPatient1)); + Long goldenPatient2Pid = runInTransaction(()->myIdHelperService.getPidOrNull(goldenPatient2)); assertFalse(myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenPatient1Pid, goldenPatient2Pid).isPresent()); assertFalse(myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenPatient2Pid, goldenPatient1Pid).isPresent()); @@ -99,8 +99,8 @@ public class MdmLinkSvcTest extends BaseMdmR4Test { Patient goldenPatient1 = createGoldenPatient(); Patient goldenPatient2 = createGoldenPatient(); - Long goldenPatient1Pid = myIdHelperService.getPidOrNull(goldenPatient1); - Long goldenPatient2Pid = myIdHelperService.getPidOrNull(goldenPatient2); + Long goldenPatient1Pid = runInTransaction(()->myIdHelperService.getPidOrNull(goldenPatient1)); + Long goldenPatient2Pid = runInTransaction(()->myIdHelperService.getPidOrNull(goldenPatient2)); assertFalse(myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenPatient1Pid, goldenPatient2Pid).isPresent()); assertFalse(myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenPatient2Pid, goldenPatient1Pid).isPresent()); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcMultipleEidModeTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcMultipleEidModeTest.java index e08fb1a8453..addad17c83e 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcMultipleEidModeTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcMultipleEidModeTest.java @@ -142,10 +142,12 @@ public class MdmMatchLinkSvcMultipleEidModeTest extends BaseMdmR4Test { List possibleDuplicates = myMdmLinkDaoSvc.getPossibleDuplicates(); assertThat(possibleDuplicates, hasSize(1)); - List duplicatePids = Stream.of(patient1, patient2) + Patient finalPatient1 = patient1; + Patient finalPatient2 = patient2; + List duplicatePids = runInTransaction(()->Stream.of(finalPatient1, finalPatient2) .map(this::getGoldenResourceFromTargetResource) .map(myIdHelperService::getPidOrNull) - .collect(Collectors.toList()); + .collect(Collectors.toList())); //The two GoldenResources related to the patients should both show up in the only existing POSSIBLE_DUPLICATE MdmLink. MdmLink mdmLink = possibleDuplicates.get(0); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java index b3236ccaa39..4fb94698aa7 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java @@ -268,10 +268,12 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test { List possibleDuplicates = myMdmLinkDaoSvc.getPossibleDuplicates(); assertThat(possibleDuplicates, hasSize(1)); - List duplicatePids = Stream.of(patient1, patient2) + Patient finalPatient1 = patient1; + Patient finalPatient2 = patient2; + List duplicatePids = runInTransaction(()->Stream.of(finalPatient1, finalPatient2) .map(this::getGoldenResourceFromTargetResource) .map(myIdHelperService::getPidOrNull) - .collect(Collectors.toList()); + .collect(Collectors.toList())); //The two GoldenResources related to the patients should both show up in the only existing POSSIBLE_DUPLICATE MdmLink. MdmLink mdmLink = possibleDuplicates.get(0); @@ -360,7 +362,7 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test { assertThat(incomingJanePatient, is(possibleMatchWith(janePatient, janePatient2))); //Ensure there is no successful MATCH links for incomingJanePatient - Optional matchedLinkForTargetPid = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(incomingJanePatient)); + Optional matchedLinkForTargetPid = runInTransaction(()->myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(incomingJanePatient))); assertThat(matchedLinkForTargetPid.isPresent(), is(false)); logAllLinks(); diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java index f79d0594f8e..25fcb0c30aa 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java @@ -11,6 +11,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome; import javax.annotation.Nonnull; +import javax.transaction.Transactional; import java.util.List; /* @@ -37,6 +38,7 @@ public interface IFhirResourceDaoCodeSystem ext List findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest); + @Transactional @Nonnull IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType theCode, IPrimitiveType theSystem, CD theCoding, RequestDetails theRequestDetails); diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java index 0a974c578dd..c3099e657f5 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java @@ -26,13 +26,17 @@ import ca.uhn.fhir.rest.api.server.RequestDetails; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; +import org.springframework.transaction.annotation.Transactional; public interface IFhirResourceDaoValueSet extends IFhirResourceDao { + @Transactional T expand(IIdType theId, ValueSetExpansionOptions theOptions, RequestDetails theRequestDetails); + @Transactional T expand(T theSource, ValueSetExpansionOptions theOptions); + @Transactional T expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions); void purgeCaches(); diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java index 26cfae738b3..38f03ca6350 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java @@ -25,6 +25,7 @@ import ca.uhn.fhir.jpa.api.model.ExpungeOutcome; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.RequestDetails; import org.hl7.fhir.instance.model.api.IBaseBundle; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Nullable; import java.util.Date; @@ -59,6 +60,7 @@ public interface IFhirSystemDao extends IDao { * * @param theRequestDetails TODO */ + @Transactional MT metaGetOperation(RequestDetails theRequestDetails); /** diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/InterceptorUserDataMapDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/InterceptorUserDataMapDstu2Test.java index fed8bf429f8..b14713707dd 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/InterceptorUserDataMapDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/InterceptorUserDataMapDstu2Test.java @@ -28,7 +28,6 @@ import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; @@ -42,6 +41,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; @@ -87,10 +87,10 @@ public class InterceptorUserDataMapDstu2Test { public void testException() throws Exception { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_id=foo"); - HttpResponse status = ourClient.execute(httpGet); - IOUtils.closeQuietly(status.getEntity().getContent()); + try (CloseableHttpResponse status = ourClient.execute(httpGet)) { + assertEquals(400, status.getStatusLine().getStatusCode()); + } - ourLog.info(myMapCheckMethods.toString()); await().until(() -> myMapCheckMethods, contains("incomingRequestPostProcessed", "incomingRequestPreHandled", "preProcessOutgoingException", "handleException", "processingCompleted")); } @@ -99,13 +99,9 @@ public class InterceptorUserDataMapDstu2Test { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1"); try (CloseableHttpResponse status = ourClient.execute(httpGet)) { - - for (int i = 0; i < 10; i++) { - if (!myMapCheckMethods.contains("processingCompletedNormally")) { - Thread.sleep(100); - } - } - + assertEquals(200, status.getStatusLine().getStatusCode()); + String output = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.debug(output); } await().until(() -> myMapCheckMethods, contains("incomingRequestPostProcessed", "incomingRequestPreHandled", "outgoingResponse", "processingCompletedNormally", "processingCompleted"));