Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fetch liferay entity through custom-finder in custom plugin portlet?

How can we fetch liferay entities through custom-finder using custom SQL?

  1. Following is my sql query written in default.xml (I have trimmed down the query to the bare minimum so that the logic remains simple. Since it included a few functions and joins we couldn't use DynamicQuery API ):

    SELECT
        grp.*
    FROM
        Group_
    WHERE
        site = 1
        AND active_ = 1
        AND type_ <> 3
    
  2. Relevant code in MyCustomGroupFinderImpl.java:

    Session session = null;
    
    try {
        session = openSession();
    
        // fetches the query string from the default.xml
        String sql = CustomSQLUtil.get(FIND_ONLY_ACTIVE_SITES);
    
        SQLQuery sqlQuery = session.createSQLQuery(sql);
    
        sqlQuery.addEntity("Group_", GroupImpl.class);
        // sqlQuery.addEntity("Group_", PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.model.impl.GroupImpl"));
    
        return (List<Group>) QueryUtil.list(sqlQuery, getDialect(), 0, QueryUtil.ALL_POS);
    }
    catch (Exception e) {
        throw new SystemException(e);
    }
    finally {
        closeSession(session);
    }
    

This above code won't work as the GroupImpl class is present in portal-impl.jar and this jar cannot be used in custom portlet.

I also tried using sqlQuery.addEntity("Group_", PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.model.impl.GroupImpl"))
But this above code throws exception:

com.liferay.portal.kernel.exception.SystemException:
    com.liferay.portal.kernel.dao.orm.ORMException:
        org.hibernate.MappingException:
            Unknown entity: com.liferay.portal.model.impl.GroupImpl

But the same code works for our custom-entity, if we write sqlQuery.addEntity("MyCustomGroup", MyCustomGroupImpl.class);.

Thanks

like image 476
Prakash K Avatar asked Apr 09 '13 07:04

Prakash K


1 Answers

I found out from the liferay forum thread that instead of session = openSession(); we would need to fetch the session from liferaySessionFactory as follows to make it work:

// fetch liferay's session factory
SessionFactory sessionFactory = (SessionFactory) PortalBeanLocatorUtil.locate("liferaySessionFactory");

Session session = null;

try {
    // open session using liferay's session factory
    session = sessionFactory.openSession();

    // fetches the query string from the default.xml
    String sql = CustomSQLUtil.get(FIND_ONLY_ACTIVE_SITES);

    SQLQuery sqlQuery = session.createSQLQuery(sql);

    // use portal class loader, since this is portal entity
    sqlQuery.addEntity("Group_", PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.model.impl.GroupImpl"));

    return (List<Group>) QueryUtil.list(sqlQuery, getDialect(), 0, QueryUtil.ALL_POS);
}
catch (Exception e) {
    throw new SystemException(e);
}
finally {
    sessionFactory.closeSession(session); // edited as per the comment on this answer
    // closeSession(session);
}

Hope this helps somebody on stackoverflow, also I found a nice tutorial regarding custom-sql which also uses the same approach.

like image 60
Prakash K Avatar answered Oct 20 '22 19:10

Prakash K