New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TRUNK-5557: Improve performance of ConceptService.getConceptsByMapping #2961
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -471,7 +471,8 @@ public List<ConceptDatatype> getAllConceptDatatypes(boolean includeRetired) thro | |
} | ||
|
||
/** | ||
* @see org.openmrs.api.db.ConceptDAO#getConceptDatatypes(java.lang.String) | ||
* @param name the name of the ConceptDatatype | ||
* @return a List of ConceptDatatype whose names start with the passed name | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
public List<ConceptDatatype> getConceptDatatypes(String name) throws DAOException { | ||
|
@@ -817,7 +818,7 @@ public List<ConceptSet> getSetsContainingConcept(Concept concept) { | |
/** | ||
* returns a list of n-generations of parents of a concept in a concept set | ||
* | ||
* @param Concept current | ||
* @param current | ||
* @return List<Concept> | ||
* @throws DAOException | ||
*/ | ||
|
@@ -1016,54 +1017,30 @@ public void remove() { | |
} | ||
|
||
} | ||
|
||
/** | ||
* @see org.openmrs.api.db.ConceptDAO#getConceptsByMapping(String, String, boolean) | ||
*/ | ||
@Override | ||
@SuppressWarnings("unchecked") | ||
@Deprecated | ||
public List<Concept> getConceptsByMapping(String code, String sourceName, boolean includeRetired) { | ||
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ConceptMap.class); | ||
|
||
// make this criteria return a list of concepts | ||
Criteria criteria = createSearchConceptMapCriteria(code, sourceName, includeRetired); | ||
criteria.setProjection(Projections.property("concept")); | ||
|
||
//join to the conceptReferenceTerm table | ||
criteria.createAlias("conceptReferenceTerm", "term"); | ||
|
||
// match the source code to the passed code | ||
if (Context.getAdministrationService().isDatabaseStringComparisonCaseSensitive()) { | ||
criteria.add(Restrictions.eq("term.code", code).ignoreCase()); | ||
} else { | ||
criteria.add(Restrictions.eq("term.code", code)); | ||
} | ||
|
||
// join to concept reference source and match to the h17Code or source name | ||
criteria.createAlias("term.conceptSource", "source"); | ||
if (Context.getAdministrationService().isDatabaseStringComparisonCaseSensitive()) { | ||
criteria.add(Restrictions.or(Restrictions.eq("source.name", sourceName).ignoreCase(), Restrictions.eq( | ||
"source.hl7Code", sourceName).ignoreCase())); | ||
} else { | ||
criteria.add(Restrictions.or(Restrictions.eq("source.name", sourceName), Restrictions.eq("source.hl7Code", | ||
sourceName))); | ||
} | ||
|
||
criteria.createAlias("concept", "concept"); | ||
|
||
if (!includeRetired) { | ||
// ignore retired concepts | ||
criteria.add(Restrictions.eq("concept.retired", false)); | ||
} else { | ||
// sort retired concepts to the end of the list | ||
criteria.addOrder(Order.asc("concept.retired")); | ||
} | ||
|
||
// we only want distinct concepts | ||
criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE); | ||
|
||
return (List<Concept>) criteria.list(); | ||
} | ||
|
||
|
||
/** | ||
* @see org.openmrs.api.db.ConceptDAO#getConceptIdsByMapping(String, String, boolean) | ||
*/ | ||
@Override | ||
@SuppressWarnings("unchecked") | ||
public List<Integer> getConceptIdsByMapping(String code, String sourceName, boolean includeRetired) { | ||
Criteria criteria = createSearchConceptMapCriteria(code, sourceName, includeRetired); | ||
criteria.setProjection(Projections.property("concept.conceptId")); | ||
return (List<Integer>) criteria.list(); | ||
} | ||
|
||
/** | ||
* @see org.openmrs.api.db.ConceptDAO#getConceptByUuid(java.lang.String) | ||
*/ | ||
|
@@ -2074,4 +2051,43 @@ private Criteria createSearchDrugByMappingCriteria(String code, ConceptSource co | |
} | ||
return searchCriteria; | ||
} | ||
|
||
private Criteria createSearchConceptMapCriteria(String code, String sourceName, boolean includeRetired) { | ||
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ConceptMap.class); | ||
|
||
//join to the conceptReferenceTerm table | ||
criteria.createAlias("conceptReferenceTerm", "term"); | ||
|
||
// match the source code to the passed code | ||
if (Context.getAdministrationService().isDatabaseStringComparisonCaseSensitive()) { | ||
criteria.add(Restrictions.eq("term.code", code).ignoreCase()); | ||
} else { | ||
criteria.add(Restrictions.eq("term.code", code)); | ||
} | ||
|
||
// join to concept reference source and match to the h17Code or source name | ||
criteria.createAlias("term.conceptSource", "source"); | ||
if (Context.getAdministrationService().isDatabaseStringComparisonCaseSensitive()) { | ||
criteria.add(Restrictions.or(Restrictions.eq("source.name", sourceName).ignoreCase(), Restrictions.eq( | ||
"source.hl7Code", sourceName).ignoreCase())); | ||
} else { | ||
criteria.add(Restrictions.or(Restrictions.eq("source.name", sourceName), Restrictions.eq("source.hl7Code", | ||
sourceName))); | ||
} | ||
|
||
criteria.createAlias("concept", "concept"); | ||
|
||
if (!includeRetired) { | ||
// ignore retired concepts | ||
criteria.add(Restrictions.eq("concept.retired", false)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that cache should be evicted also when concept.retired changes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just pushed a follow-up commit that:
|
||
} else { | ||
// sort retired concepts to the end of the list | ||
criteria.addOrder(Order.asc("concept.retired")); | ||
} | ||
|
||
// we only want distinct concepts | ||
criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE); | ||
|
||
return criteria; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd make use of cache here as well with:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this out, and it was a lot slower (2x) than the way the service method is implemented. I also am not a fan of services calling DAOs which then call different services. I actually think we should leave this dao method implementation alone but Deprecate the method, as it is no longer used by the Service layer at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. Fair point to not call services in DAOs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is due to the fact that by iterating over the concept ids and calling getConcept(id), we also leverage hibernate's use of ehcache in a more efficient manner than by running an HQL query with an "in" clause on ids.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am in favour of leaving this dao method implementation alone.