views:

384

answers:

3

I have a class, Order, which I persist to a database using NHibernate. There is a folder futher down in the web application that contains an object that inherits from Order, for our purposes, we can call it CustomOrder. I use CustomOrder to place a few properties onto the Order object for UI purposes. The properties don't actually have to be saved to the database.

When I pass the CustomOrder class to my generic save method that just takes in an Order object, NHibernate complains:

Unknown entity class: CustomOrder.

I don't need to persist the custom fields to the database, but I'd like to keep this inheritance structure. Am I thinking in the wrong terms or doing something I shouldn't be doing?

Save Code

public object Save(Order obj, object userID) {
        Order o = (Order)obj;  
        ISession session = NHibernateHelper.GetCurrentSession();
        ITransaction tx = session.BeginTransaction();

        session.Save(o);

After the case in the first line of the method, .NET still identifies it as CustomerOrder.

A: 

Try explicitly casting it to Order:

public void SaveOrder(Order order)
{
    var orderToSave = (Order)order;
    [...]
}
Jamie Ide
Funny thing, that's exactly what my code does, but when I check it in debug mode, the variable further on after the case still reads CustomOrder.
Josh
Can you post the save method? My advice was a bit of a shot in the dark and there may be a nuance to casting that I'm unaware of.
Jamie Ide
Casting the order to the type it is already declared is useless.This is not C++ where an instance is interpreted as it where of another type. Casting does not change the type. The framework always knows the actual type, you cannot cheat.
Stefan Steinegger
A: 

It's been a while, but I believe that you should be able to specify that the derived class should be persisted as an object of the base class in the hibernate mapping file.

McWafflestix
Is there a workaround to having to provide a discriminator for a subclass?
Josh
+2  A: 
  1. You cannot change the type of a instance in .NET. There is no casting or whatever that makes it possible.
  2. When loading the instance from the DB, NHibernate wants to create the same type you stored. That's why it wants a mapping for CustomOrder.

How ever you implement it: you need to create a new instance of Order.

// get the CustomOrder from somewhere
CustomOrder customOrder;
// create an instance of Order and store it.
session.Save(customOrder.GetOrder());


class CustomOrder
{

    // just one of many ways: a method on the CustomOrder to create 
    // instance of Order
    public GetOrder()
    {
        return new Order()
        {
            property1 = this.property1,
            property2 = this.property2,
            property3 = this.property3
        }
    }
}

You can use Reflection to do this automatically. Or take a look at MemberwiseClone().

Stefan Steinegger
+1 this is exactly what I was going to suggest (and the only way to accomplish this).
Stuart Childs