Don't update modified time when performing NOOP update in JPA
This commit is contained in:
parent
bfd6066e99
commit
706af5d579
|
@ -1319,17 +1319,18 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, this, theUpdateTime, theEntity, theResource, existingParams);
|
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, this, theUpdateTime, theEntity, theResource, existingParams);
|
||||||
|
|
||||||
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, true);
|
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, true);
|
||||||
|
if (changed.isChanged()) {
|
||||||
|
theEntity.setUpdated(theUpdateTime);
|
||||||
|
if (theResource instanceof IResource) {
|
||||||
|
theEntity.setLanguage(((IResource) theResource).getLanguage().getValue());
|
||||||
|
} else {
|
||||||
|
theEntity.setLanguage(((IAnyResource) theResource).getLanguageElement().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
theEntity.setUpdated(theUpdateTime);
|
newParams.setParamsOn(theEntity);
|
||||||
if (theResource instanceof IResource) {
|
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
|
||||||
theEntity.setLanguage(((IResource) theResource).getLanguage().getValue());
|
populateFullTextFields(myContext, theResource, theEntity);
|
||||||
} else {
|
|
||||||
theEntity.setLanguage(((IAnyResource) theResource).getLanguageElement().getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newParams.setParamsOn(theEntity);
|
|
||||||
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
|
|
||||||
populateFullTextFields(myContext, theResource, theEntity);
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, false);
|
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, false);
|
||||||
|
|
|
@ -144,6 +144,17 @@ public class CircularQueueCaptureQueriesListener extends BaseCaptureQueriesListe
|
||||||
return getQueriesForCurrentThreadStartingWith("delete");
|
return getQueriesForCurrentThreadStartingWith("delete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log all captured UPDATE queries
|
||||||
|
*/
|
||||||
|
public void logUpdateQueriesForCurrentThread() {
|
||||||
|
List<String> queries = getUpdateQueriesForCurrentThread()
|
||||||
|
.stream()
|
||||||
|
.map(CircularQueueCaptureQueriesListener::formatQueryAsSql)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
ourLog.info("Select Queries:\n{}", String.join("\n", queries));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log all captured SELECT queries
|
* Log all captured SELECT queries
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4,6 +4,7 @@ import ca.uhn.fhir.jpa.util.CircularQueueCaptureQueriesListener;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||||
import net.ttddyy.dsproxy.listener.SingleQueryCountHolder;
|
import net.ttddyy.dsproxy.listener.SingleQueryCountHolder;
|
||||||
|
import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel;
|
||||||
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
|
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -102,7 +103,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
|
||||||
|
|
||||||
DataSource dataSource = ProxyDataSourceBuilder
|
DataSource dataSource = ProxyDataSourceBuilder
|
||||||
.create(retVal)
|
.create(retVal)
|
||||||
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
|
.logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
|
||||||
// .logSlowQueryBySlf4j(10, TimeUnit.SECONDS)
|
// .logSlowQueryBySlf4j(10, TimeUnit.SECONDS)
|
||||||
// .countQuery(new ThreadQueryCountHolder())
|
// .countQuery(new ThreadQueryCountHolder())
|
||||||
.beforeQuery(new BlockLargeNumbersOfParamsListener())
|
.beforeQuery(new BlockLargeNumbersOfParamsListener())
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package ca.uhn.fhir.jpa.dao.r4;
|
package ca.uhn.fhir.jpa.dao.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.util.TestUtil;
|
import ca.uhn.fhir.jpa.util.TestUtil;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
@ -85,6 +87,58 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateNotModifiedDoesNotAffectDates() {
|
||||||
|
IIdType id = runInTransaction(() -> {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue("2");
|
||||||
|
return myPatientDao.create(p).getId().toUnqualified();
|
||||||
|
});
|
||||||
|
|
||||||
|
String createTime = runInTransaction(()->{
|
||||||
|
List<ResourceTable> allResources = myResourceTableDao.findAll();
|
||||||
|
assertEquals(1, allResources.size());
|
||||||
|
ResourceTable resourceTable = allResources.get(0);
|
||||||
|
|
||||||
|
List<ResourceHistoryTable> allHistory = myResourceHistoryTableDao.findAll();
|
||||||
|
assertEquals(1, allHistory.size());
|
||||||
|
ResourceHistoryTable historyTable = allHistory.get(0);
|
||||||
|
|
||||||
|
assertEquals(resourceTable.getUpdated().getValueAsString(), historyTable.getUpdated().getValueAsString());
|
||||||
|
return resourceTable.getUpdated().getValueAsString();
|
||||||
|
});
|
||||||
|
|
||||||
|
myCaptureQueriesListener.clear();
|
||||||
|
runInTransaction(()->{
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId(id.getIdPart());
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue("2");
|
||||||
|
myPatientDao.update(p);
|
||||||
|
});
|
||||||
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
|
// TODO: it'd be nice if this was lower
|
||||||
|
assertEquals(6, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
|
||||||
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
|
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
||||||
|
assertThat(myCaptureQueriesListener.getInsertQueriesForCurrentThread(), empty());
|
||||||
|
assertThat(myCaptureQueriesListener.getDeleteQueriesForCurrentThread(), empty());
|
||||||
|
|
||||||
|
runInTransaction(()->{
|
||||||
|
List<ResourceTable> allResources = myResourceTableDao.findAll();
|
||||||
|
assertEquals(1, allResources.size());
|
||||||
|
ResourceTable resourceTable = allResources.get(0);
|
||||||
|
|
||||||
|
List<ResourceHistoryTable> allHistory = myResourceHistoryTableDao.findAll();
|
||||||
|
assertEquals(1, allHistory.size());
|
||||||
|
ResourceHistoryTable historyTable = allHistory.get(0);
|
||||||
|
|
||||||
|
assertEquals(createTime, historyTable.getUpdated().getValueAsString());
|
||||||
|
assertEquals(createTime, resourceTable.getUpdated().getValueAsString());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateProfilesIgnored() {
|
public void testDuplicateProfilesIgnored() {
|
||||||
String name = "testDuplicateProfilesIgnored";
|
String name = "testDuplicateProfilesIgnored";
|
||||||
|
|
|
@ -132,6 +132,11 @@
|
||||||
The second bug is that one case wasn't properly handled: when a resourceId with no version is provided.
|
The second bug is that one case wasn't properly handled: when a resourceId with no version is provided.
|
||||||
This executed the case where only resource type is provided.
|
This executed the case where only resource type is provided.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
When updating a resource in the JPA server, if the contents have not actually changed
|
||||||
|
the resource version is not updated and no new version is created. In this situation,
|
||||||
|
the update time was modified however. It will no longer be updated.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.7.0" date="2019-02-06" description="Gale">
|
<release version="3.7.0" date="2019-02-06" description="Gale">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue