Rename columns in code mapping

This commit is contained in:
James Agnew 2019-07-05 09:03:03 -04:00
parent 6e20b53979
commit 2a6436af23
20 changed files with 376 additions and 31 deletions

View File

@ -60,6 +60,7 @@ public class TermCodeSystemVersion implements Serializable {
@JoinColumn(name = "CODESYSTEM_PID", referencedColumnName = "PID", nullable = true, foreignKey = @ForeignKey(name = "FK_CODESYSVER_CS_ID"))
private TermCodeSystem myCodeSystem;
@SuppressWarnings("unused")
@OneToOne(mappedBy = "myCurrentVersion", optional = true)
private TermCodeSystem myCodeSystemHavingThisVersionAsCurrentVersionIfAny;

View File

@ -56,8 +56,13 @@ public class TermConceptMapGroup implements Serializable {
@OneToMany(mappedBy = "myConceptMapGroup")
private List<TermConceptMapGroupElement> myConceptMapGroupElements;
@Column(name= "CONCEPT_MAP_URL", length = 200, nullable = true)
private String myConceptMapUrl;
@Column(name= "SOURCE_VS", length = 200, nullable = true)
private String mySourceValueSet;
@Column(name= "TARGET_VS", length = 200, nullable = true)
private String myTargetValueSet;
public TermConceptMap getConceptMap() {

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.entity;
* #L%
*/
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
@ -54,9 +55,16 @@ public class TermConceptMapGroupElement implements Serializable {
@OneToMany(mappedBy = "myConceptMapGroupElement")
private List<TermConceptMapGroupElementTarget> myConceptMapGroupElementTargets;
@Column(name = "CONCEPT_MAP_URL", length = 200)
private String myConceptMapUrl;
@Column(name = "SYSTEM_URL", length = 200)
private String mySystem;
@Column(name = "SYSTEM_VERSION", length = 200)
private String mySystemVersion;
@Column(name = "VALUESET_URL", length = 200)
private String myValueSet;
public String getCode() {
@ -64,6 +72,7 @@ public class TermConceptMapGroupElement implements Serializable {
}
public void setCode(String theCode) {
Validate.notBlank(theCode, "theCode must not be blank");
myCode = theCode;
}

View File

@ -54,9 +54,13 @@ public class TermConceptMapGroupElementTarget implements Serializable {
@Column(name = "TARGET_EQUIVALENCE", length = 50)
private ConceptMapEquivalence myEquivalence;
@Column(name = "CONCEPT_MAP_URL", length = 200)
private String myConceptMapUrl;
@Column(name = "SYSTEM_URL", length = 200)
private String mySystem;
@Column(name = "SYSTEM_VERSION", length = 200)
private String mySystemVersion;
@Column(name = "VALUESET_URL", length = 200)
private String myValueSet;
public String getCode() {

View File

@ -1288,6 +1288,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
if (group.hasElement()) {
TermConceptMapGroupElement termConceptMapGroupElement;
for (ConceptMap.SourceElementComponent element : group.getElement()) {
if (isBlank(element.getCode())) {
// FIXME: JA - send this to an interceptor message so it can be
// output
continue;
}
termConceptMapGroupElement = new TermConceptMapGroupElement();
termConceptMapGroupElement.setConceptMapGroup(termConceptMapGroup);
termConceptMapGroupElement.setCode(element.getCode());

View File

@ -27,12 +27,12 @@ import com.google.common.reflect.ClassPath.ClassInfo;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.InstantType;
import org.hl7.fhir.r4.model.Patient;
import javax.persistence.*;
import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@ -54,6 +54,7 @@ public class TestUtil {
/**
* This is really only useful for unit tests, do not call otherwise
*/
@SuppressWarnings("UnstableApiUsage")
public static void scanEntities(String packageName) throws IOException, ClassNotFoundException {
ImmutableSet<ClassInfo> classes = ClassPath.from(TestUtil.class.getClassLoader()).getTopLevelClasses(packageName);
Set<String> names = new HashSet<String>();
@ -80,6 +81,10 @@ public class TestUtil {
scan(theClazz, theNames, theIsSuperClass);
for (Field nextField : theClazz.getDeclaredFields()) {
if (Modifier.isStatic(nextField.getModifiers())) {
continue;
}
ourLog.info(" * Scanning field: {}", nextField.getName());
scan(nextField, theNames, theIsSuperClass);
@ -90,6 +95,22 @@ public class TestUtil {
}
}
boolean isTransient = nextField.getAnnotation(Transient.class) != null;
if (!isTransient) {
boolean hasColumn = nextField.getAnnotation(Column.class) != null;
boolean hasJoinColumn = nextField.getAnnotation(JoinColumn.class) != null;
OneToMany oneToMany = nextField.getAnnotation(OneToMany.class);
OneToOne oneToOne = nextField.getAnnotation(OneToOne.class);
boolean isOtherSideOfOneToManyMapping = oneToMany != null && isNotBlank(oneToMany.mappedBy());
boolean isOtherSideOfOneToOneMapping = oneToOne != null && isNotBlank(oneToOne.mappedBy());
Validate.isTrue(
hasColumn ||
hasJoinColumn ||
isOtherSideOfOneToManyMapping ||
isOtherSideOfOneToOneMapping, "Non-transient has no @Column or @JoinColumn: " + nextField);
}
}
if (theClazz.getSuperclass().equals(Object.class)) {

View File

@ -3,10 +3,10 @@ package ca.uhn.fhir.jpa.config;
import ca.uhn.fhir.jpa.util.TestUtil;
import org.junit.Test;
public class IdentifierLengthTest {
public class JpaEntityTest {
@Test
public void testIdentifierLength() throws Exception {
public void testEntitiesAreValid() throws Exception {
TestUtil.scanEntities(ca.uhn.fhir.jpa.model.entity.ResourceTable.class.getPackage().getName());
TestUtil.scanEntities(ca.uhn.fhir.jpa.entity.TermConcept.class.getPackage().getName());
}

View File

@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.config.TestR4Config;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
import ca.uhn.fhir.jpa.interceptor.PerformanceTracingLoggingInterceptor;
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
@ -34,6 +33,7 @@ import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
@ -294,11 +294,13 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
protected ICacheWarmingSvc myCacheWarmingSvc;
@Autowired
protected SubscriptionRegistry mySubscriptionRegistry;
protected IServerInterceptor myInterceptor;
@Autowired
private JpaValidationSupportChainR4 myJpaValidationSupportChainR4;
private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor;
private List<Object> mySystemInterceptors;
protected IServerInterceptor myInterceptor;
@Autowired
private DaoRegistry myDaoRegistry;
@After()
public void afterCleanupDao() {
@ -402,6 +404,19 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
}
}
@SuppressWarnings("unchecked")
protected void upload(String theClasspath) throws IOException {
String resource = loadResource(theClasspath);
IParser parser = EncodingEnum.detectEncoding(resource).newParser(myFhirCtx);
IBaseResource resourceParsed = parser.parseResource(resource);
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceParsed.getIdElement().getResourceType());
dao.update(resourceParsed);
}
protected String loadResource(String theClasspath) throws IOException {
return IOUtils.toString(FhirResourceDaoR4ValidateTest.class.getResourceAsStream(theClasspath), Charsets.UTF_8);
}
@AfterClass
public static void afterClassClearContextBaseJpaR4Test() {

View File

@ -3,12 +3,13 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.term.TranslationMatch;
import ca.uhn.fhir.jpa.term.TranslationRequest;
import ca.uhn.fhir.jpa.term.TranslationResult;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r4.model.UriType;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
@ -19,6 +20,9 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.io.IOException;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*;
public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
@ -1037,6 +1041,24 @@ public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
});
}
@Test
public void testUploadAndApplyR4DemoConceptMap() throws IOException {
upload("/r4/ConceptMap-icd-sct.xml");
CodeableConcept sourceCode = new CodeableConcept();
sourceCode.addCoding()
.setSystem("http://snomed.info/sct")
.setCode("263204007");
TranslationRequest request = new TranslationRequest();
request.setCodeableConcept(sourceCode);
request.setTargetSystem(new UriType("http://hl7.org/fhir/sid/icd-10-us"));
TranslationResult outcome = myConceptMapDao.translate(request, mySrd);
assertEquals("S52.209A", outcome.getMatches().get(1).getConcept().getCode());
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -1,8 +1,6 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
@ -13,7 +11,6 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.IValidatorModule;
import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@ -417,21 +414,6 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
}
}
@SuppressWarnings("unchecked")
private void upload(String theClasspath) throws IOException {
String resource = loadResource(theClasspath);
IBaseResource resourceParsed = myFhirCtx.newJsonParser().parseResource(resource);
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceParsed.getIdElement().getResourceType());
dao.update(resourceParsed);
}
private String loadResource(String theClasspath) throws IOException {
return IOUtils.toString(FhirResourceDaoR4ValidateTest.class.getResourceAsStream(theClasspath), Charsets.UTF_8);
}
@Autowired
private DaoRegistry myDaoRegistry;
private IBaseResource findResourceByIdInBundle(Bundle vss, String name) {
IBaseResource retVal = null;
for (BundleEntryComponent next : vss.getEntry()) {

View File

@ -0,0 +1,57 @@
<ConceptMap xmlns="http://hl7.org/fhir">
<id value="sct-icd"/>
<url value="http://hl7.org/fhir/ConceptMap/103"/>
<identifier>
<system value="urn:ietf:rfc:3986"/>
<value value="urn:uuid:53cd62ee-033e-414c-9f58-3ca97b5ffc3b"/>
</identifier>
<version value="4.0.0"/>
<name value="SNOMED CT to ICD-10-CM mappings for fracture of ulna"/>
<status value="draft"/>
<experimental value="true"/>
<date value="2012-06-13"/>
<publisher value="HL7, Inc"/>
<contact>
<name value="FHIR project team (example)"/>
<telecom>
<system value="url"/>
<value value="http://hl7.org/fhir"/>
</telecom>
</contact>
<description value="Example rule-based mappings between SNOMED CT to ICD-10-CM for fracture of ulna"/>
<jurisdiction>
<coding>
<system value="http://unstats.un.org/unsd/methods/m49/m49.htm"/>
<code value="840"/>
<display value="United States of America"/>
</coding>
</jurisdiction>
<purpose value="Show example rule based mappings"/>
<copyright value="Creative Commons 0"/>
<sourceCanonical value="http://snomed.info/id?fhir_vs"/>
<targetCanonical value="http://hl7.org/fhir/sid/icd-10-us"/>
<group>
<source value="http://snomed.info/sct"/>
<sourceVersion value="March 2015 US Edition"/>
<target value="http://hl7.org/fhir/sid/icd-10-us"/>
<targetVersion value="2015"/>
<element>
<code value="263204007"/>
<target>
<code value="S52.209A"/>
<equivalence value="narrower"/>
<comment value="The target mapping to ICD-10-CM is narrower, since additional patient data on the encounter
(initial vs. subsequent) and fracture type is required for a valid ICD-10-CM mapping."/>
</target>
</element>
<element>
<target>
<code value="S52.209D"/>
<equivalence value="narrower"/>
<comment value="The target mapping to ICD-10-CM is narrower, since additional patient data on the encounter
(initial vs. subsequent), fracture type and healing (for subsequent encounter) is required
for a valid ICD-10-CM mapping."/>
</target>
</element>
</group>
</ConceptMap>

View File

@ -30,6 +30,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static org.apache.commons.lang3.StringUtils.isBlank;
public class Migrator {
private static final Logger ourLog = LoggerFactory.getLogger(Migrator.class);
@ -83,7 +85,12 @@ public class Migrator {
try {
next.execute();
} catch (SQLException e) {
throw new InternalErrorException("Failure executing task \"" + next.getDescription() + "\", aborting! Cause: " + e.toString(), e);
String description = next.getDescription();
if (isBlank(description)) {
description = next.getClass().getSimpleName();
}
String prefix = "Failure executing task \"" + description + "\", aborting! Cause: ";
throw new InternalErrorException(prefix + e.toString(), e);
}
myChangesCount += next.getChangesCount();

View File

@ -30,6 +30,7 @@ public abstract class BaseTableTask<T extends BaseTableTask> extends BaseTask {
}
public T setTableName(String theTableName) {
Validate.notBlank(theTableName);
myTableName = theTableName;
return (T) this;
}

View File

@ -0,0 +1,67 @@
package ca.uhn.fhir.jpa.migrate.taskdef;
import ca.uhn.fhir.jpa.migrate.JdbcUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.Set;
public class RenameColumnTask extends BaseTableTask<RenameColumnTask> {
private static final Logger ourLog = LoggerFactory.getLogger(RenameColumnTask.class);
private String myOldName;
private String myNewName;
public void setOldName(String theOldName) {
Validate.notBlank(theOldName);
myOldName = theOldName;
}
public void setNewName(String theNewName) {
Validate.notBlank(theNewName);
myNewName = theNewName;
}
@Override
public void execute() throws SQLException {
Set<String> columnNames = JdbcUtils.getColumnNames(getConnectionProperties(), getTableName());
boolean haveOldName = columnNames.contains(myOldName.toUpperCase());
boolean haveNewName = columnNames.contains(myNewName.toUpperCase());
if (haveOldName && haveNewName) {
throw new SQLException("Can not rename " + getTableName() + "." + myOldName + " to " + myNewName + " because both columns exist!");
}
if (!haveOldName && !haveNewName) {
throw new SQLException("Can not rename " + getTableName() + "." + myOldName + " to " + myNewName + " because neither column exists!");
}
if (haveNewName) {
ourLog.info("Column {} already exists on table {} - No action performed", myNewName, getTableName());
return;
}
String sql = "";
switch (getDriverType()) {
case DERBY_EMBEDDED:
sql = "RENAME COLUMN " + getTableName() + "." + myOldName + " TO " + myNewName;
break;
case MARIADB_10_1:
case MYSQL_5_7:
sql = "ALTER TABLE " + getTableName() + " CHANGE COLUMN " + myOldName + " TO " + myNewName;
break;
case POSTGRES_9_4:
sql = "ALTER TABLE " + getTableName() + " RENAME COLUMN " + myOldName + " TO " + myNewName;
break;
case MSSQL_2012:
sql = "sp_rename '" + getTableName() + "." + myOldName + "', '" + myNewName + "', 'COLUMN'";
break;
case ORACLE_12C:
sql = "ALTER TABLE " + getTableName() + " RENAME COLUMN " + myOldName + " TO " + myNewName;
break;
}
ourLog.info("Renaming column {} on table {} to {}", myOldName, getTableName(), myNewName);
executeSql(getTableName(), sql);
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.migrate.tasks;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,13 +20,13 @@ package ca.uhn.fhir.jpa.migrate.tasks;
* #L%
*/
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
import ca.uhn.fhir.jpa.migrate.taskdef.AddColumnTask;
import ca.uhn.fhir.jpa.migrate.taskdef.ArbitrarySqlTask;
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTableColumnTypeTask;
import ca.uhn.fhir.jpa.migrate.taskdef.CalculateHashesTask;
import ca.uhn.fhir.jpa.migrate.tasks.api.BaseMigrationTasks;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.util.VersionEnum;
import java.util.Arrays;
@ -53,8 +53,29 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
init340();
init350();
init360();
init400();
}
private void init400() {
Builder version = forVersion(VersionEnum.V4_0_0);
version.onTable("TRM_CONCEPT_MAP_GROUP")
.renameColumn("myConceptMapUrl", "CONCEPT_MAP_URL")
.renameColumn("mySourceValueSet", "SOURCE_VS")
.renameColumn("myTargetValueSet", "TARGET_VS");
version.onTable("TRM_CONCEPT_MAP_GRP_ELEMENT")
.renameColumn("myConceptMapUrl", "CONCEPT_MAP_URL")
.renameColumn("mySystem", "SYSTEM_URL")
.renameColumn("mySystemVersion", "SYSTEM_VERSION")
.renameColumn("myValueSet", "VALUESET_URL");
version.onTable("TRM_CONCEPT_MAP_GRP_ELM_TGT")
.renameColumn("myConceptMapUrl", "CONCEPT_MAP_URL")
.renameColumn("mySystem", "SYSTEM_URL")
.renameColumn("mySystemVersion", "SYSTEM_VERSION")
.renameColumn("myValueSet", "VALUESET_URL");
}
private void init360() {

View File

@ -167,6 +167,15 @@ public class BaseMigrationTasks<T extends Enum> {
return new BuilderAddForeignKey(theForeignKeyName);
}
public BuilderWithTableName renameColumn(String theOldName, String theNewName) {
RenameColumnTask task = new RenameColumnTask();
task.setTableName(myTableName);
task.setOldName(theOldName);
task.setNewName(theNewName);
addTask(task);
return this;
}
public class BuilderAddIndexWithName {
private final String myIndexName;

View File

@ -0,0 +1,87 @@
package ca.uhn.fhir.jpa.migrate.taskdef;
import ca.uhn.fhir.jpa.migrate.JdbcUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.junit.Test;
import java.sql.SQLException;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.*;
public class RenameColumnTaskTest extends BaseTest {
@Test
public void testColumnAlreadyExists() throws SQLException {
executeSql("create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))");
RenameColumnTask task = new RenameColumnTask();
task.setTableName("SOMETABLE");
task.setDescription("Drop an index");
task.setOldName("myTextCol");
task.setNewName("TEXTCOL");
getMigrator().addTask(task);
getMigrator().migrate();
assertThat(JdbcUtils.getColumnNames(getConnectionProperties(), "SOMETABLE"), containsInAnyOrder("PID", "TEXTCOL"));
}
@Test
public void testColumnDoesntAlreadyExist() throws SQLException {
executeSql("create table SOMETABLE (PID bigint not null, myTextCol varchar(255))");
RenameColumnTask task = new RenameColumnTask();
task.setTableName("SOMETABLE");
task.setDescription("Drop an index");
task.setOldName("myTextCol");
task.setNewName("TEXTCOL");
getMigrator().addTask(task);
getMigrator().migrate();
assertThat(JdbcUtils.getColumnNames(getConnectionProperties(), "SOMETABLE"), containsInAnyOrder("PID", "TEXTCOL"));
}
@Test
public void testNeitherColumnExists() throws SQLException {
executeSql("create table SOMETABLE (PID bigint not null)");
RenameColumnTask task = new RenameColumnTask();
task.setTableName("SOMETABLE");
task.setOldName("myTextCol");
task.setNewName("TEXTCOL");
getMigrator().addTask(task);
try {
getMigrator().migrate();
fail();
} catch (InternalErrorException e) {
assertEquals("Failure executing task \"RenameColumnTask\", aborting! Cause: java.sql.SQLException: Can not rename SOMETABLE.myTextCol to TEXTCOL because neither column exists!", e.getMessage());
}
}
@Test
public void testBothColumnsExist() throws SQLException {
executeSql("create table SOMETABLE (PID bigint not null, PID2 bigint)");
RenameColumnTask task = new RenameColumnTask();
task.setTableName("SOMETABLE");
task.setOldName("PID");
task.setNewName("PID2");
getMigrator().addTask(task);
try {
getMigrator().migrate();
fail();
} catch (InternalErrorException e) {
assertEquals("Failure executing task \"RenameColumnTask\", aborting! Cause: java.sql.SQLException: Can not rename SOMETABLE.PID to PID2 because both columns exist!", e.getMessage());
}
}
}

View File

@ -24,14 +24,20 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.r4.model.CanonicalType;
@ -58,6 +64,8 @@ public class ResourceLinkExtractor {
private ISearchParamRegistry mySearchParamRegistry;
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster;
public void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, boolean theFailOnInvalidReference, RequestDetails theRequest) {
String resourceType = theEntity.getResourceType();
@ -111,7 +119,17 @@ public class ResourceLinkExtractor {
}
if (nextObject instanceof CanonicalType) {
nextObject = new Reference(((CanonicalType) nextObject).getValueAsString());
StorageProcessingMessage msg = new StorageProcessingMessage();
msg.setMessage("Ignoring canonical reference (indexing canonidcal is not yet supported): " + ((CanonicalType) nextObject).getValueAsString());
HookParams params = new HookParams()
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest)
.add(StorageProcessingMessage.class, msg);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
// nextObject = new Reference(((CanonicalType) nextObject).getValueAsString());
// wasCanonical = true;
return;
}
IIdType nextId;

View File

@ -225,6 +225,20 @@
returned that includes the resource ID and the version ID for the deleted
resource.
</action>
<action type="fix">
A number of columns in the JPA Terminology Services ConceptMap tables were not
explicitly annotated with @Column, so the DB columns that were generated had
Java ugly field names as their SQL column names. These have been renamed, and
entries in the JPA migrator tool have been added for anyone upgrading.
</action>
<action type="fix">
Field values with a datatype of <![CDATA[<code>canonical</code>]]> were indexed as
though they were explicit resource references by the JPA server. This led to
errors about external references not being supported when uploading various
resources (e.g. Questionnaires with HL7-defined ValueSet references). This has
been corrected. Note that at this time, we do not index canonical references
at all (as we were previously doing it incorrectly). This will be improved soon.
</action>
</release>
<release version="3.8.0" date="2019-05-30" description="Hippo">
<action type="fix">