Bloggers recientes

Maarten van Heiningen

4 Mensajes
22 de marzo de 2017

David H Nebinger

46 Mensajes
21 de marzo de 2017

Orsolya Kuti

2 Mensajes
14 de marzo de 2017

Sushil Patidar

9 Mensajes
7 de marzo de 2017

Jamie Sammons

7 Mensajes
6 de marzo de 2017

Zeno Rocha

15 Mensajes
28 de febrero de 2017

Sarai Diaz

1 Mensajes
28 de febrero de 2017

Neil Jin

17 Mensajes
20 de febrero de 2017

Kyle Joseph Stiemann

9 Mensajes
17 de febrero de 2017

Andy Wu

1 Mensajes
16 de febrero de 2017
« Atrás

Custom Finder for Portal Entities in a Plugin

Company Blogs 22 de junio de 2012 Por David Truong Staff

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 =

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.


Respuestas anidadas Autor Fecha
very cool, now it all makes sense. Wilson Man 22 de junio de 2012 13:10
May be the SQLQuery(Impl) could be extended so... Sampsa Sohlman 23 de junio de 2012 15:24
NIce! 다니엘 Daniel Bastos 28 de junio de 2012 7:42
FYI You are using _classMap in a non ... Jelmer Kuperus 9 de julio de 2012 2:55
Nice Post... Jay Patel 10 de julio de 2012 7:41
Hey jelmer, Good points. I will update my... David Truong 10 de julio de 2012 12:59
Hey Sampsa, That would make things too easy... David Truong 10 de julio de 2012 13:01
It is a bit challenging to add a new action... Muhammed Shakir 7 de octubre de 2012 3:09
Great! i asked to me the same question "If... Harvey Tamayo 29 de noviembre de 2016 16:10

very cool, now it all makes sense.
Publicado el día 22/06/12 13:10.
May be the SQLQuery(Impl) could be extended so that if there is entity's interface as parameter then, it would find the implementation automatically.

Anyway, good post.
Publicado el día 23/06/12 15:24.
Publicado el día 28/06/12 7:42.

You are using _classMap in a non threadsafe way

Also by holding on to the impl class references in a map you are effectively preventing the webapp classloader from being garbage collected. (not a problem if you just use it to load classes from the ROOT webapp, since it's not hotdeployable, but it is if you use this same trick do load classes from another standalone portlet) You'll be blowing up your permgen space
Publicado el día 9/07/12 2:55.
Publicado el día 10/07/12 7:41.
Hey jelmer,

Good points. I will update my code so that if the classLoader is not ROOT it won't put it in the map. You should consider filing a jira issue also because this code is a copy of what is from DynamicFactoryUtil

Thanks for your comments guys
Publicado el día 10/07/12 12:59 en respuesta a Jay Patel.
Hey Sampsa,

That would make things too easy for you guys then! Haha JK. Good suggestion. It is even more valid because the look up is already being done for dynamic queries. Very little code would have to be written for this improvement.
Publicado el día 10/07/12 13:01 en respuesta a David Truong.
It is a bit challenging to add a new action with a custom jsp and ensuring that the jsp is wrapped into the theme properly. I have got the solution and it works like a charm. You can find the solution here :
Publicado el día 7/10/12 3:09 en respuesta a David Truong.
Great! i asked to me the same question "If DynamicQueryFactoryUtil.forClass can, me too. Right?" thanks.
For now i have other issue, i try to do a CustomSQL Query where IS SELECT * customTable INNER JOIN JournalArticle. For now i don't find other solution that modifying portlet-hbm adding the portal table configuration from portal-hbm. Like is suggested in But if you are interested and you find other solution, that will be great. Regards from Colombia.
Publicado el día 29/11/16 16:10.