views:

144

answers:

2

We're developing an application using Nhibernate as the data access layer.

One of the things I'm struggling with is finding a way to map 2 objects to the same table.

We have an object which is suited to data entry, and another which is used in more of a batch process.

The table contains all the columns for the data entry and some additional info for the batch processes.

When it's in a batch process I don't want to load all the data just a subset, but I want to be able to update the values in the table.

Does nhibernate support multiple objects pointed at the same table? and what is the thing that allows this?

I tried it a while ago and I remember that if you do a query for one of the objects it loads double the amount but i'm not so sure I didn't miss something.

e.g.

10 data entry objects + 10 batch objects

So 20 object instead of 10.

Can anyone shed any light on this?

I should clarify that these objects are 2 different objects which in my mind should not be polymorphic in behaviour. However they do point at the same database record, it's more that the record has a dual purpose within the application and for sake of logical partitioning they should be kept separate. (A change to one domain object should not blow up numerous screens in other modules etc).

Thanks Pete

+1  A: 

An easy way to map multiple objects to the same table is by using a discriminator column. Add an extra column to the table and have it contain a value declaring it as type "Data Entry" or "Batch Process".

You'd create two objects - one for Data Entry and Batch Process. I'm not entirely sure how you enact that in regular NHibernate XML mapping - I use Castle ActiveRecord for annotating, so you'd mark up your objects like so:

[ActiveRecord("[Big Honking Table]",
    DiscriminatorColumn = "Type",
    DiscriminatorType = "String",
    DiscriminatorValue = "Data Entry")]
public class Data Entry : ActiveRecordBase
{
   //Your stuff here!
}

[ActiveRecord("[Big Honking Table]",
    DiscriminatorColumn = "Type",
    DiscriminatorType = "String",
    DiscriminatorValue = "Batch Process")]
public class Batch Process : ActiveRecordBase
{
   //Also your stuff!
}

Here's the way to do it with NHibernate + Castle ActiveRecord: http://www.castleproject.org/activerecord/documentation/trunk/usersguide/typehierarchy.html Note that they use a parent object - I don't think that's necessary but I haven't implemented a discriminator column exactly the way you're describing, so it might be.

And here's the mapping in XML: https://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html

You can also, through the mapping, let NHibernate know which columns to load / update - if you end up just making one big object.

phyllis diller
This would work if they weren't the same record in the database, however the two objects would use the same record, just in 2 modes effectively.I have used the descriminator previously for other polymorphic behaviour this is just behaviour which doesn't suit polymorphic classes.These are two separate classes that are the same record in the db they have maybe 3 properties / columns in common with each other.
Peter
I updated the original post to include this extra info I didn't explain well in the first post.
Peter
Ahh, okay. I'm going to agree with John's comment above, then - just map two different objects to the same table and only include certain columns - without either being a subclass of the other.
phyllis diller
A: 

I suppose you just might be overengineering it just a little bit:

  • If you worry about performance, that's premature optimization (besides, retrieving less columns is not much faster, as for saving you can enable dynamic updates to only update columns that changed).
  • If you trying to protect the programmer from himself by locking down his choices, you complicating your design for not so noble a cause.

In short, based on my 10 yrs+ of experience and my somewhat limited understanding of your problem I recommend you think again about doing what you wanna do.

zvolkov
Thanks for the comments however I don't feel like I am over engineering this as the performance hit doesn't just have to take into account the speed but also the transmission time accross the wire, the amount of memory consumed, why read 15 strings into memory when you need 1. I'm not trying to lock down choices I'm trying to ensure that the application is modular as some of the requirements mean that our customers wish to re-write sections to have them work to their workflows etc.
Peter