Uploaded image for project: 'OpenMRS Core'
  1. OpenMRS Core
  2. TRUNK-5332

HibernateProviderDAO.getCountOfProviders throws an exception when there are more than one match

    Details

    • Complexity:
      Low

      Description

      To reproduce the bug add this test case to ProviderServiceTest

      @Test
      public void getCountOfProviders_shouldHandleMoreThanOneMatch() {
        
        // creating one more matching provider
        Person person = Context.getPersonService().getPerson(42);
        Set<PersonName> names = person.getNames();
        for (PersonName name : names) {
          name.setVoided(true);
        }
        PersonName personName = new PersonName("hippopotamus", "foo", "bar");
        personName.setPreferred(true);
        person.addName(personName);
        person = Context.getPersonService().savePerson(person);
        Provider provider = new Provider();
        provider.setPerson(person);
        Context.getProviderService().saveProvider(provider);
        
        // verif
        assertEquals(2, service.getCountOfProviders("Hippo").intValue());
      }
      

      And observe that the following error is being reported:

      Column "PERSONNAME2_.PREFERRED" must be in the GROUP BY list; SQL statement:
      select count(distinct (this_.provider_id)) as y0_ from provider this_ left outer join person p1_ on this_.person_id=p1_.person_id left outer join patient p1_1_ on p1_.person_id=p1_1_.patient_id left outer join person_name personname2_ on p1_.person_id=personname2_.person_id where this_.retired=? and (lower(this_.identifier) like ? or lower(this_.name) like ? or ((personname2_.voided=? and (lower(personname2_.given_name) like ? or lower(personname2_.middle_name) like ? or lower(personname2_.family_name) like ? or lower(personname2_.family_name2) like ?)))) order by personname2_.voided asc, personname2_.preferred desc, personname2_.date_created desc 
      

      Below is an obvious fix to the current method in HibernateProviderDAO:

      @Override
      public Long getCountOfProviders(String name, boolean includeRetired) {
        Criteria criteria = prepareProviderCriteria(name, includeRetired);
        return (long) criteria.list().size();
      }
      

      But perhaps someone wants to dig further as to why the existing code doesn't work.

      Credits to chine zoheir for uncovering the bug.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                samuel34 Samuel Male
                Reporter:
                mksd Dimitri R
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: