title: Custom Liferay service function failing to openSession()
body: <p>This problem has been frustrating me for quite some time and I'm hoping someone can help me out here.  I am using Service Builder to expose a custom entity to the JSON Web Service API, which I want to use in my portlet.  I cannot use Dynamic Queries, and since there will be several more complicated queries later on with multiple joins, I feel custom sql is the best option.  However, I'm not even able to begin the query because the call to openSession() throws a NPE.  Here's my code (I apologize for the length, but I really have no idea what I'm doing wrong here and I'm just trying to include everything that's relevant):</p>
  
  <p>ServiceImpl class:</p>
  
  <pre><code>@JSONWebService
  public class MBMessagesAsDiscussionPrimeServiceImpl extends MBMessagesAsDiscussionPrimeServiceBaseImpl {
      @Override
      public List&lt;MBMessagesAsDiscussionPrime&gt; getMessagesAsDiscussionPrime() throws SystemException {
          MBMessagesAsDiscussionPrimeFinder finder = new MBMessagesAsDiscussionPrimeFinderImpl();
          return finder.findByGroupId();
      }
  }
  </code></pre>
  
  <p>My FinderImpl class:</p>
  
  <pre><code>public class MBMessagesAsDiscussionPrimeFinderImpl extends BasePersistenceImpl&lt;MBMessagesAsDiscussionPrime&gt; implements MBMessagesAsDiscussionPrimeFinder {
  
      @Override
      public List&lt;MBMessagesAsDiscussionPrime&gt; findByGroupId() throws SystemException {
          SessionFactory sessionFactory = (SessionFactory) PortalBeanLocatorUtil.locate("liferaySessionFactory");
  
          Session session = null;
          try {
              session = sessionFactory.openSession(); //exception here
  
              //other stuff here, eventually...
          } catch (Exception e) {
              throw new SystemException(e);
          } finally {
              closeSession(session); //throws NPE here
          }
      }
  }
  </code></pre>
  
  <p>custom query:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;custom-sql&gt;
      &lt;sql
          id="com.test.portlet.service.persistence.MBMessagesAsDiscussionPrimeFinder.findByGroupId"&gt;
          &lt;![CDATA[
              SELECT * FROM MBMessage, MBThread
              WHERE
                  (MBMessage.threadId = MBThread.threadId) AND
                  (MBThread.groupID = ?) 
              ORDER BY
                  MBThread.rootMessageId DESC, MBMessage.messageId ASC
          ]]&gt;
      &lt;/sql&gt;    
  &lt;/custom-sql&gt;
  </code></pre>
  
  <p>and service.xml:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE service-builder PUBLIC
  "-//Liferay//DTD Service Builder 6.1.0//EN"
  "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd"&gt;
  
  &lt;service-builder package-path="com.test.portlet"&gt;
      &lt;namespace&gt;MBMessagesAsDiscussionPrime&lt;/namespace&gt;
  
      &lt;entity name="MBMessagesAsDiscussionPrime" uuid="true" local-service="true" remote-service="true"&gt;
  
          &lt;column name="messageId" type="long" primary="true" /&gt;
          &lt;column name="threadId" type="long"/&gt;
          &lt;column name="userId" type="long"/&gt;
          &lt;column name="userName" type="String"/&gt;
          &lt;column name="body" type="String"/&gt;
  
          &lt;reference package-path="com.liferay.portlet.messageboards" entity="MBMessage" /&gt;
          &lt;reference package-path="com.liferay.portlet.messageboards" entity="MBThread" /&gt;
      &lt;/entity&gt;    
  &lt;/service-builder&gt;
  </code></pre>
  
  <p>The service function is visible from localhost:8080/custom-query-portlet/api/jsonws, which is where I'm calling it from.  Is there something in particular I need to do since this is being called remotely, besides setting @JSONWebService on the ServiceImpl class?  Please, someone help me out on this.  It's driving me up a wall!</p>