JPA performance tweaks: Avoid unneccesary fulltext index pass during transaction and tag lookup

This commit is contained in:
jamesagnew 2015-10-25 12:18:21 -04:00
parent 60f4c27f5b
commit c31900b827
6 changed files with 76 additions and 9 deletions

View File

@ -684,6 +684,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
Set<TagDefinition> allDefs = new HashSet<TagDefinition>(); Set<TagDefinition> allDefs = new HashSet<TagDefinition>();
theEntity.setHasTags(false);
TagList tagList = ResourceMetadataKeyEnum.TAG_LIST.get(theResource); TagList tagList = ResourceMetadataKeyEnum.TAG_LIST.get(theResource);
if (tagList != null) { if (tagList != null) {
for (Tag next : tagList) { for (Tag next : tagList) {
@ -726,9 +728,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
} }
} }
} }
if (theEntity.getTags().size() == 0) {
theEntity.setHasTags(false);
}
String title = ResourceMetadataKeyEnum.TITLE.get(theResource); String title = ResourceMetadataKeyEnum.TITLE.get(theResource);
if (title != null && title.length() > BaseHasResource.MAX_TITLE_LENGTH) { if (title != null && title.length() > BaseHasResource.MAX_TITLE_LENGTH) {

View File

@ -35,14 +35,12 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Index; import javax.persistence.Index;
import javax.persistence.Lob;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Transient; import javax.persistence.Transient;
import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import ca.uhn.fhir.jpa.search.IndexNonDeletedInterceptor; import ca.uhn.fhir.jpa.search.IndexNonDeletedInterceptor;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -50,7 +48,7 @@ import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
//@formatter:off //@formatter:off
@Indexed(/*interceptor=IndexNonDeletedInterceptor.class*/) @Indexed(interceptor=IndexNonDeletedInterceptor.class)
@Entity @Entity
@Table(name = "HFJ_RESOURCE", uniqueConstraints = {}, indexes= { @Table(name = "HFJ_RESOURCE", uniqueConstraints = {}, indexes= {
@Index(name = "IDX_RES_DATE", columnList="RES_UPDATED"), @Index(name = "IDX_RES_DATE", columnList="RES_UPDATED"),

View File

@ -33,13 +33,18 @@ public class IndexNonDeletedInterceptor implements EntityIndexingInterceptor<Res
@Override @Override
public IndexingOverride onAdd(ResourceTable entity) { public IndexingOverride onAdd(ResourceTable entity) {
if (entity.getDeleted() == null) { if (entity.getDeleted() == null) {
if (entity.getIndexStatus() != null) {
return IndexingOverride.APPLY_DEFAULT; return IndexingOverride.APPLY_DEFAULT;
} }
}
return IndexingOverride.SKIP; return IndexingOverride.SKIP;
} }
@Override @Override
public IndexingOverride onUpdate(ResourceTable entity) { public IndexingOverride onUpdate(ResourceTable entity) {
if (entity.getIndexStatus() == null) {
return IndexingOverride.SKIP;
}
if (entity.getDeleted() == null) { if (entity.getDeleted() == null) {
return IndexingOverride.UPDATE; return IndexingOverride.UPDATE;
} }

View File

@ -57,7 +57,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect"); extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect");

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import java.util.List; import java.util.List;
@ -31,6 +32,8 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
FullTextEntityManager ftem = Search.getFullTextEntityManager(myEntityManager); FullTextEntityManager ftem = Search.getFullTextEntityManager(myEntityManager);
ftem.purgeAll(ResourceTable.class); ftem.purgeAll(ResourceTable.class);
ftem.flushToIndexes(); ftem.flushToIndexes();
myDaoConfig.setSchedulingDisabled(true);
} }
@Test @Test
@ -80,6 +83,68 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
} }
/**
* When processing transactions, we do two passes. Make sure we don't update the
* lucene index twice since that would be inefficient
*/
@Test
public void testSearchDontReindexForUpdateWithIndexDisabled() {
Patient patient;
SearchParameterMap map;
patient = new Patient();
patient.getText().setDiv("<div>DIVAAA</div>");
patient.addName().addGiven("NAMEAAA");
IIdType pId1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
map = new SearchParameterMap();
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), contains(pId1));
map = new SearchParameterMap();
map.add(Constants.PARAM_TEXT, new StringParam("DIVAAA"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), contains(pId1));
/*
* Update but don't reindex
*/
patient = new Patient();
patient.setId(pId1);
patient.getText().setDiv("<div>DIVBBB</div>");
patient.addName().addGiven("NAMEBBB");
myPatientDao.update(patient, null, false);
map = new SearchParameterMap();
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), contains(pId1));
map = new SearchParameterMap();
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEBBB"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), not(contains(pId1)));
myPatientDao.update(patient, null, true);
map = new SearchParameterMap();
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), empty());
map = new SearchParameterMap();
map.add(Patient.SP_NAME, new StringParam("NAMEBBB"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), contains(pId1));
map = new SearchParameterMap();
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEBBB"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), contains(pId1));
map = new SearchParameterMap();
map.add(Constants.PARAM_TEXT, new StringParam("DIVBBB"));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), contains(pId1));
}
@Test @Test
public void testSearchWithChainedParams() { public void testSearchWithChainedParams() {
String methodName = "testSearchWithChainedParams"; String methodName = "testSearchWithChainedParams";

View File

@ -12,7 +12,7 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry including="**/*.java" kind="src" path="src/main/resources"/> <classpathentry kind="src" path="src/main/resources"/>
<classpathentry including="**/*.java" kind="src" path="src/test/resources"/> <classpathentry including="**/*.java" kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes> <attributes>