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

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

    XMLWordPrintable

    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.

        Gliffy Diagrams

          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: