|
I have a number of cases where columns exist solely for operational purposes (purging, partitioning, data warehouse reporting). I'd like a way to populate these values even though the object model does not contain them.
As an example, say every table has a column called PARTITION_ID. The partition id does not exist in the object model, but can either be derived from some properties on the object model, grabbed from some thread local session information, or calculated from some static method. Basically, it should be some logic that can be placed into a UserType. I have experimented with a few different ways of doing this:
dynamic-map entity-mode:
Using this entity mode I am able to get the flexibility I need, but it comes at the cost of having to turn large object hierarchies into a large map of maps. Also, where it is only a table or two that has columns like this, I am forced to use this entity-mode for all of my objects.
dynamic-components:
If I added a map to every object, this would work great. Unfortunately, at that point I might as weel just add the columns I wanted then :) Of course, if I could somehow make a map available on all object via a proxy, there might be some way to work with this.
custom user types:
This is where I have had the most success, but I've had to really hack things up. Basically by creating a CompositeUserType I can map a property that does exist on the object to two columns, one which is the proper column for the property and one which holds this additional unrelated data:
<property name="description">
<column name="DESCRIPTION"/>
<column name="PARTITION_ID"/>
<type name="PartitionHackType">
<param name="typeName">string</param>
</type>
</property>
where the "typeName" param is simply the name of a Type I can retrieve by calling TypeFactory.basic().
Of course, this is just a hack.
I've discussed using triggers with the DBAs, but they are unhappy with the associated performance issues and additional maintenance. Using a combination of the oracle context (basically just a session hashmap), event listeners, and default values coming from the context, I have a possible solution but it has more moving parts than I am comfortable with. In the end, the DBAs don't understand why I'm having any difficulty at all with these columns and feel it must be a limitation in hibernate (which in some ways it appears to be).
In my ideal world, I would just be able to say something like:
<property name="partitionId" db-only="true">
<column name="PARTITION_ID"/>
<type name="PartitionType"/>
</property>
or
<column name="PARTITION_ID" type="PartitionType"/>
The first case seems like it would be easier to fit into the current architecture (at least from the few times I have actually looked deep into the bowels of hibernate), but the second option seems much more explicit (I guess it might just be syntactic sugar).
I'm open to any suggestions others might have on how I might do this without any changes to hibernate, but I'd also like to hear what the chances of getting something like this into hibernate are (either by coding it myself or asking for a new feature in jira).
|