Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-75399

In a service builder finder, an error is produced when you sort by a field that belongs to a compound pk

    Details

      Description

      In a service builder finder, an error is produced when you sort by a field that belongs to a compound pk.

      The problem is produced when you have a service with a compound pk, for example "fooId" and "barId" and try ordering with one of that fields in a finder.

      The problem is:

      • In hibernate, fields of a compound key must be prefixed with "id." keyword
      • But in our code we are checking the field to be used in sort clause must exists in entity fields, so adding "id." causes an error.

      Code setup

      See full code in attached file lps75399-src.zip
      See compiled code in attached files lps75399-api-1.0.0.jar and lps75399-service-1.0.0.jar

      Detailed information about problematic code:

      1. Create a servicebuilder called "Foo" with a compound pk of fields fooId and barId
        	<entity local-service="true" name="Foo" remote-service="true" uuid="true">
        
        		<!-- PK fields -->
        
        		<column name="fooId" primary="true" type="long" />
        		<column name="barId" primary="true" type="long" />
        
      2. Add a finder for fooId and groupId fields findByF_G
                <finder name="F_G" return-type="Collection">
                    <finder-column name="fooId" />
                    <finder-column name="groupId" />
                </finder>
        
      3. Create a method that call to finder findByF_G with a OrderByComparator:
        	public void checkLPS75399Sort(String field) {
        		System.out.println("start checkLPS75399");
        		System.out.println("sort by " + field);
        		fooPersistence.findByF_G(0, 0, -1, -1, new OrderByField(field));
        		System.out.println("end checkLPS75399");
        	}
        

      Steps to reproduce

      1. Download lps75399-src.zip and:
        1. Regenerate services (gradlew buildService ; gradlew build ; gradlew jar)
        2. Install generated jar files
      2. Go to control panel script console and execute following groovy script:
        try {
            com.example.service.FooLocalServiceUtil.checkLPS75399Sort("barId") ;
        }
        catch(Throwable t) {
            t.printStackTrace(out);
        }
        
        • Expected behavior: code is executed without any error
        • Wrong behavior: following exception is thrown
          com.liferay.portal.kernel.exception.SystemException: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.QueryException: could not resolve property: barId of: com.example.model.impl.FooImpl [SELECT foo FROM com.example.model.impl.FooImpl foo WHERE foo.id.fooId = ? AND foo.groupId = ? ORDER BY foo.barId DESC]
          	at com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl.processException(BasePersistenceImpl.java:264)
          	at com.example.service.persistence.impl.FooPersistenceImpl.findByF_G(FooPersistenceImpl.java:1645)
          	at com.example.service.persistence.impl.FooPersistenceImpl.findByF_G(FooPersistenceImpl.java:1528)
          	at com.example.service.impl.FooLocalServiceImpl.checkLPS75399Sort(FooLocalServiceImpl.java:70)
          [...]
          	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
          	at java.lang.Thread.run(Thread.java:745)
          Caused by: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.QueryException: could not resolve property: barId of: com.example.model.impl.FooImpl [SELECT foo FROM com.example.model.impl.FooImpl foo WHERE foo.id.fooId = ? AND foo.groupId = ? ORDER BY foo.barId DESC]
          	at com.liferay.portal.dao.orm.hibernate.ExceptionTranslator.translate(ExceptionTranslator.java:33)
          	at com.liferay.portal.dao.orm.hibernate.SessionImpl.createQuery(SessionImpl.java:92)
          	at com.liferay.portal.dao.orm.hibernate.SessionImpl.createQuery(SessionImpl.java:78)
          	at com.liferay.portal.kernel.dao.orm.ClassLoaderSession.createQuery(ClassLoaderSession.java:110)
          	at com.example.service.persistence.impl.FooPersistenceImpl.findByF_G(FooPersistenceImpl.java:1618)
          	... 202 more
          Caused by: org.hibernate.QueryException: could not resolve property: barId of: com.example.model.impl.FooImpl [SELECT foo FROM com.example.model.impl.FooImpl foo WHERE foo.id.fooId = ? AND foo.groupId = ? ORDER BY foo.barId DESC]
          	at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81)
          	at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:75)
          [...]
          	at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
          	at com.liferay.portal.dao.orm.hibernate.SessionImpl.createQuery(SessionImpl.java:89)
          	... 205 more
          

      Note: The exception is produced because hibernate expects compound pk to be queried using "id." prefix.
      If we try ordering using "id.barId" field:

      try {
          com.example.service.FooLocalServiceUtil.checkLPS75399Sort("id.barId") ;
      }
      catch(Throwable t) {
          t.printStackTrace(out);
      }
      

      ...a exception is thrown at Liferay code, see:

      java.lang.IllegalArgumentException: Unknown column name id.barId
      	at com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl.getColumnName(BasePersistenceImpl.java:452)
      	at com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl.appendOrderByComparator(BasePersistenceImpl.java:409)
      	at com.liferay.portal.kernel.service.persistence.impl.BasePersistenceImpl.appendOrderByComparator(BasePersistenceImpl.java:388)
      	at com.example.service.persistence.impl.FooPersistenceImpl.findByF_G(FooPersistenceImpl.java:1603)
      	at com.example.service.persistence.impl.FooPersistenceImpl.findByF_G(FooPersistenceImpl.java:1528)
      	at com.example.service.impl.FooLocalServiceImpl.checkLPS75399Sort(FooLocalServiceImpl.java:70)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      

        Attachments

        1. Fixed.png
          Fixed.png
          30 kB
        2. lps75399-api-1.0.0.jar
          25 kB
        3. lps75399-service-1.0.0.jar
          47 kB
        4. lps75399-src.zip
          289 kB
        5. new_lps75399-src.7z
          199 kB

          Activity

            People

            • Assignee:
              sharry.shi Sharry Shi
              Reporter:
              jorge.diaz Jorge Diaz
              Participants of an Issue:
              Recent user:
              Csaba Turcsan
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                1 year, 50 weeks, 3 days ago

                Packages

                Version Package
                7.0.0 DXP FP33
                7.0.0 DXP SP7
                7.0.5 CE GA6
                7.0.X
                7.1.0 M1
                7.1.X
                Master