Blogs
Sometimes you need to write a custom finder for a table that belongs to core. In my case it was JournalArticle. My client wanted to avoid using the ext-plugin as much as possible so I had to try to figure out a way to do it within a portlet plugin.
I tried to use dynamic queries as a solution but it turned out to be inadequate because I was unable to group by (I wanted to get the latest articles with a certain structureId).
I needed a custom finder but for awhile I thought this was impossible because you needed to load the Impl of a model during the query which is inaccessible since it is part of portal-impl. But my experimentation with dynamic queries was not in vain because I figured... if dynamic queries can figure out a way to load the impl class I could probably do the same.
So here is the class I wrote.
It consists of two basic methods:
public static Class getImplClass(Class clazz, ClassLoader classLoader) {
if (!clazz.getName().endsWith("Impl")) {
String implClassName = clazz.getPackage().getName() + ".impl." +
clazz.getSimpleName() + "Impl";
clazz = _classMap.get(implClassName);
if (clazz == null) {
try {
if (classLoader == null) {
Thread currentThread = Thread.currentThread();
classLoader = currentThread.getContextClassLoader();
}
clazz = classLoader.loadClass(implClassName);
_classMap.put(implClassName, clazz);
}
catch (Exception e) {
_log.error("Unable find model " + implClassName, e);
}
}
}
return clazz;
}
public static Session openPortalSession() throws ORMException {
return sessionFactory.openSession();
}
private static Log _log = LogFactoryUtil.getLog(CustomFinderHelperUtil.class);
private static Map> _classMap = new HashMap>();
private static SessionFactory sessionFactory =
(SessionFactory)PortalBeanLocatorUtil.locate("liferaySessionFactory");
So basically in my customFinder instead of doing
session = openSession();
I did
session = CustomFinderHelperUtil.openPortalSession();
and instead of doing
q.addEntity("JournalArticle", JournalArticleImpl.class));
I did
q.addEntity("JournalArticle", CustomFinderHelperUtil.getImplClass(
JournalArticle.class, true));
(I created a extra method that took a boolean to use the portalClassLoader, you can load it using PortalClassLoaderUtil.getPortalClassLoader())
Hopefully this helps some you guys out.

