问题
How can we fetch liferay entities through custom-finder using custom SQL?
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 useDynamicQuery
API ):SELECT grp.* FROM Group_ WHERE site = 1 AND active_ = 1 AND type_ <> 3
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
回答1:
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.
来源:https://stackoverflow.com/questions/15895484/how-to-fetch-liferay-entity-through-custom-finder-in-custom-plugin-portlet