db-torque-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brendan Miller <bmil...@dotster.com>
Subject access to Peer.getOMClass for new objects?
Date Thu, 19 Feb 2009 18:38:33 GMT

I have a table in my schema that uses an inheritance map for one of the
columns:

    <column name="SERVICE_TYPE" javaName="ServiceType"
      size="50" type="VARCHAR" inheritance="single">
      <inheritance key="CUSTOM"   class="CustomService"   extends="foo.service.Service"/>
      <inheritance key="SPECIAL"  class="SpecialService"  extends="foo.service.Service"/>
    </column>

There may be other inheritance keys, but this gives a concrete example.

I understand that when you ServicePeer.retrieveByPK(id) the magic of
ServicePeer.getOMClass and ServicePeer.row2Object will construct the
proper type (either CustomService or SpecialService) depending on the
value of the service_type column.  (I also know that if your database
contains values for that column that are not listed as inheritance keys,
you have major fail.)

It would be nice to have a method to construct a new Service object
based on the value for the service_type column.  I cannot create a
Service as in

    Service service = new Service();
    service.setServiceType("CUSTOM");

because Service is abstract.  (I know I could change this, but that's
not the point.)  I'd really like a method that used the getOMClass
logic to instantiate the right object class.  Unfortunately, getOMClass
is too tied to com.workingdogs.village.Record.

To get around this, I wrote my own peer method:

    public static Service createFromServiceType(final String serviceType)
        throws TorqueException
    {
        try {
            Record record = new Record()
            {
                public Value getValue(int i) throws DataSetException
                {
                    try {
                        return new Value(null, 0, 0)
                        {
                            public String asString()
                            {
                                return serviceType;
                            }
                        };
                    }
                    catch (SQLException e) {
                        throw new DataSetException("Couldn't return service type: "+
                                serviceType);
                    }
                }
            };

            Class omClass = getOMClass(record, 1);

            return (Service) omClass.newInstance();
        }
        catch (InstantiationException e) {
            throw new TorqueException("Couldn't create Service from "+serviceType, e);
        }   
        catch (IllegalAccessException e) {
            throw new TorqueException("Couldn't create Service from "+serviceType, e);
        }   
    }

Now I can write

    Service service = ServicePeer.createFromServiceType(serviceType);

and have the correct type of Service object instantiated.  This is
useful when serviceType is passed into my application via XML, user
input, some form, etc.

It's a little brutal to create the anonymous Record class to provide the 
hook to Record.getValue so that getOMClass continues to work, but it's
all I could come up with short of duplicating the getOMClass code.  I
suppose this could be decoupled in Peer.vm to provide two methods:

    public static Class getOMClass(Record record, int offset)

and

    public static Class getOMClass(String classKey)

Something to think about, especially as the Village removal is
considered.  I'm guessing that getOMClass gets reworked in a VillageFree
age anyway?

Any other thoughts?

Brendan

---------------------------------------------------------------------
To unsubscribe, e-mail: torque-user-unsubscribe@db.apache.org
For additional commands, e-mail: torque-user-help@db.apache.org


Mime
View raw message