On Fri, 17 Jan 2003 12:27:02 +0000, Jim Clayson <[EMAIL PROTECTED]>
wrote:

||| searchCriteriaVO has
|||     engineType (all,1, 2 ,3)
|||     condition (any,good, fair, poor)
|||     registrationFromDate (could be null)
|||     registrationToDate(could be null)
||| 
||| The above criteria could produce a fairly large number of unique 
||| combinations and thus that same number of finders.

I'm in the same boat, and whether or not this is a 'best practice' I
couldn't say, but I'll show you what I've written and you can decide. We
have a search page that has 5 criteria, one of which is always required.
The other four can be there or not, all, some or none. We end up with 16
finders then. You are correct about building up a dynamic SQL query being
rather an easy thing to do, but generating the finder names is a bit more
work. Here's what I did. I'll just dump the code and then discuss
afterwards.

public Collection generateFinderAndCall(EJBLocalHome home,
                                                                            String 
providerId,
                                                                                
ClaimSearchAttributes attrs)
{
        long start = System.currentTimeMillis();
                
        Collection list = null;
        StringBuffer name = new StringBuffer("findByProviderId");
        List args = new ArrayList();

        args.add(providerId);

        if (attrs.getMemberId() != null)
        {
                name.append("MemberId");
                args.add(attrs.getMemberId());
        }

        if (attrs.getTcn() != null)
        {
                name.append("Tcn");
                args.add(new BigDecimal(attrs.getTcn()));
        }

        if (attrs.getFromDate() != null)
        {
                name.append("FromDate");
                args.add(attrs.getFromDate());
        }

        if (attrs.getThroughDate() != null)
        {
                name.append("ThroughDate");
                args.add(attrs.getThroughDate());
        }

        String methodName = name.toString();
        List classes = new ArrayList();
                
        for (Iterator i = args.iterator(); i.hasNext(); )
        {
                classes.add(i.next().getClass());
        }

        try
        {
                Method method = home.getClass().getMethod(methodName, (Class[])
classes.toArray(new Class[classes.size()]));
                        
                list = (Collection) method.invoke(home, args.toArray());
        }
        catch (Exception e)
        {
                LOG.error("error getting/calling finder", e);
                list = new ArrayList();
        }
                
        return list;
}

This builds up the name of the finder by appending each piece if the VO's
getter for that attribute doesn't return null. The names of the finders are
generated in order so that this regardless of what criteria are passed in,
a proper finder name will be generated. Each argument is added to a
collection, which is then walked to get the class of each argument. This is
converted into a Class[] so we can pass it to Class#getMethod to get the
desired method directly off the Home interface rather than having to do
Class#getMethods and loop over them until we find the right finder. Once
the method is in hand we execute it on the home, passing in the collection
of arguments, casting the result to Collection and then returning that or
an empty collection if it fails. 

This does work (I just tested it), I'm just not sure of the performance
implications of using reflection in this case.

Joey


--
http://www.joeygibson.com




-------------------------------------------------------
This SF.NET email is sponsored by: Thawte.com
Understand how to protect your customers personal information by implementing
SSL on your Apache Web Server. Click here to get our FREE Thawte Apache 
Guide: http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0029en
_______________________________________________
JBoss-user mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to