Re: superclass template question

From: Mike Kienenberger (mkienen..laska.net)
Date: Wed May 11 2005 - 11:07:08 EDT

  • Next message: Cris Daniluk: "Re: superclass template question"

    Erik Hatcher <eri..hatchersolutions.com> wrote:
    > I want to generate something like this in each of my superclasses:
    >
    > static public final User forPK(Object pk) {
    > return (User) DataObjectUtils.objectForPK(getCurrentDataContext
    > (), User.class, pk);
    > }
    >
    > First of all, is this approach reasonable to do? Are others doing
    > something similar? getCurrentDataContext() comes from my custom base
    > class and pulls the DataContext from thread local storage. My goal
    > is to keep direct Cayenne dependence out of my Tapestry code, and for
    > things like looking up an object by its primary key, I'd like to that
    > to be clean and straightforward to use. My reliance on Cayenne will
    > ideally be indirect as in the above finder method.

    You might find it easier to create a BaseDataObject class, and insert it
    between CayenneDataObject and each of your generated classes.

    Then you can put methods common to all entity classes in BaseDataObject.
    It's easier to maintain java code than Velocity java templates.

    For example (and this is two-year-old code predating DataObjectUtils):

            public Number primaryKey()
            {
                    String primaryKeysString = null;
                    Map pkAttributes = this.getObjectId().getIdSnapshot();
                    if (1 != pkAttributes.size()) throw new
    CayenneRuntimeException("multi-field primary key found.");
                    
                    Iterator pkIterator = pkAttributes.keySet().iterator();
                    String primaryKeyName = (String) pkIterator.next();
                    Number primaryKeyValue = (Number)pkAttributes.get(primaryKeyName);
                    
                    return primaryKeyValue;
            }

        /**
         *..aram aDataContext
         *..aram class1
         *..aram invoiceNumber
         *..eturn
         */
        public static GenericEntity objectMatchingPrimaryKey(DataContext
    aDataContext, Class aClass, Object aPrimaryKeyValue)
        {
            if (log.isTraceEnabled()) log.trace("in
    GenericRecord.objectMatchingPrimaryKey(DataContext, Class, Object)");

            EntityResolver anEntityResolver = aDataContext.getEntityResolver();
            DbEntity aDbEntity = anEntityResolver.lookupDbEntity(aClass);
            List pkDbAttributes = aDbEntity.getPrimaryKey();
            
            if (0 == pkDbAttributes.size()) throw new
    CayenneRuntimeException("no primary key found for class=" + aClass + ".");
            if (1 != pkDbAttributes.size()) throw new
    CayenneRuntimeException("multi-field primary key found for class=" + aClass
    + ".");
            
            DbAttribute primaryKeyDbAttribute =
    (DbAttribute)pkDbAttributes.get(0);
            String primaryKeyName = primaryKeyDbAttribute.getName();

            Expression qualifier = ExpressionFactory.matchDbExp(primaryKeyName,
    aPrimaryKeyValue);
                
            SelectQuery query = new SelectQuery(aClass, qualifier);
            List aList = aDataContext.performQuery(query);
            
            if (1 == aList.size()) return (GenericEntity)aList.get(0);
            
            if (0 == aList.size()) return null;
            
            throw new MoreThanOneException("Found " +
    String.valueOf(aList.size()) + " results for primary key=" +
    aPrimaryKeyValue);
        }

    > Second - how can I get the package name of User when generating
    > _User? I have superclasses generated into a separate package than
    > the subclass objects (which I create manually).

    I think it's a bad idea to have your superclass directly refer to the
    subclass.
    I also don't think that information is available.
    What task are you trying to accomplish?



    This archive was generated by hypermail 2.0.0 : Wed May 11 2005 - 11:05:07 EDT