I have an abstract class Example
and concrete subclasses to go along with it. I used a discriminator to pull data out of the database, like so:
<resultMap id="ExampleResultMap" class="Example">
<discriminator column="stateCode" javaType="java.lang.String">
<subMap value="AL" resultMap="AlabamaStateResultMap"/>
<subMap value="AR" resultMap="ArkansasStateResultMap"/>
[...]
</discriminator>
</resultMap>
<resultMap extends="ExampleResultMap"
id="AlabamaStateResultMap"
class="AlabamaState"/>
<resultMap extends="ExampleResultMap"
id="ArkansasStateResultMap"
class="ArkansasState"/>
[...]
Thus I have an AlabamaState
object (a subclass of the abstract Example
object) with no attributes of any kind on him. This is contrived, but the gist is that I don't have any attribute that uniquely identifies the object's type--and there's no reason I would if not for this case.
(Note: The classes aren't empty, they're behavioral, so refactoring them out of existence isn't an option.)
How do I save it back to the database?
Ideally there would be a Discriminator
for ParameterMap
s, but there doesn't seem to be one.
As far as I can tell, there are a number of undesirable solutions, among them:
- Give up and add a "getType()" method on all my subclasses that returns a static string. In this case,
AL
. (Note that I tried pretty hard to avoid needing this throughout all my code, so having this = OOD-defeat). - Make a "DB" object that's exactly like my big, complex object but happens to also have an extra string saying "Oh, btw, my TYPE is AL."
- Extract all 20 attributes I want to persist into a HashMap before inserting the object.
- Some other craziness like using the toString() or something to help me out.
Likely I'll go with the first option, but it seems rather ridiculous, doesn't it? If iBatis can create it, shouldn't it be able to persist it? What I really need is a discriminator for insert.
Am I out of luck, or am I just overlooking something obvious?
If you have no attributes belonging to your subclasses, you should consider removing these subclasses and add an enum to your former base-class, since the only purpose your subclasses serve is to differentiate the type of your objects (if I understood you correctly). Using an enum for this is easier to extend and more elegant in client code (since you can switch on the enum instead of using blocks of instanceof expressions).
If are having special implementations of certain operations on your subclasses, you could move them to the enum as well, and have your base class delegate to the implementation on the enum.
EDIT
Here is an example: