This was a great experiment, but I think I'm going to use the InheritanceMap instead--it has access to the omClass without the Village mumbo-jumbo.
pseudocode (without Exceptions, null-checks, etc): if (getTableMap().isUseInheritance) for (ColumnMap column : getTableMap().getColumns()) if (column.isUseInheritance() return Class.forName( column.getTable().getOMClass().getPackage().getName() + "." + column.getInheritanceMap(serviceType).getClassName()) .newInstance(); Brendan On Thu, Feb 19, 2009 at 10:38:33AM -0800, Brendan Miller wrote: > > 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-unsubscr...@db.apache.org > For additional commands, e-mail: torque-user-h...@db.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: torque-user-unsubscr...@db.apache.org For additional commands, e-mail: torque-user-h...@db.apache.org