Re: Retrieving via auto-generated keys

From: Mike Kienenberger (mkienen..laska.net)
Date: Fri May 28 2004 - 11:36:06 EDT

  • Next message: Gentry, Michael: "RE: Retrieving via auto-generated keys"

    Mike Elliott <mr..79.net> wrote:
    > I have a situation where I'm writing a web application. On some pages I
    need
    > to display, in a dropdown list, a subset of my users (around 750 total
    > users). That is, I need to generate something along the line of:
    >
    > <select name="selectedUser">
    > <option value="157">Biff Overbyte</option>
    > <option value="189">Steve Whotsit</option>
    > . . .
    > </select>
    >
    > What I'm talking about here is specifying as the 'value' attribute, the
    > generated integer primary key for the user, as a way of getting to the
    > full user record in the database. I can fetch this value from each user
    > instance by using the getObjectId() method, and properly generate the
    > "value=" portion of the option.
    >
    > The problem I have is what should I do in order to fetch the full record?

    > Basically, how do I go about fetching a row from the database where I know

    > the Cayenne-generated key value? I don't have a get() method for it (at
    > least directly) and it's unclear to me how to builld a query to access a
    > CayenneDataObject via its internally generated primary key.
    >
    > The overall problem I want to solve is how to display a subset of user
    names
    > from my user table as a dropdown list, then be able to fetch the
    > corresponding full User object via Cayenne. Maybe I'm going about this
    > completely wrong. If so, if anyone else has solved this problem, please
    let
    > me know.

    I've solved this problem using struts/velocity/cayenne.

    However, the way you're going about it is wrong.
    If you list primary keys as the accessor, then anyone can manually create a
    form request and put in any primary key they desire.

    The way I do it is to create a list of the objects, then index the options 0
    to list.size(). When the form is processed, I then look up the element in
    the list for the option value.

    This is the method I use to retrieve by primary key. I consider it cleaner
    than Eric's method since the idea of creating ObjectIds from application
    code seems wrong to me. (I keep expecting ObjectID to change to some
    12-byte binary value like WebObject uses for clustering support.)

        public static GenericEntity objectMatchingPrimaryKey(DataContext
    aDataContext, Class aClass, Object aPrimaryKeyValue)
        {
            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);
        }



    This archive was generated by hypermail 2.0.0 : Fri May 28 2004 - 11:34:29 EDT