Question

I am working on a legacy database which is quite intricate.
The table customers is shared with the suppliers and who created this structure used a flag to identify the customers. Since I am only interested in working with records defined as customers I've added a where clause to my mapping:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly" namespace="MyAssembly.Domain">
    <class name="Customer" table="ANSADID" mutable="false" where="ANFCLI = 'Y'">
    <composite-id>
      <key-property name="CustomerCode" column="ANCOCO" type="String" length="10"></key-property>
      <key-property name="Company" column="ANCOSO" type ="String" length="5"></key-property>
    </composite-id>
    <property name="Name" column="ANINCO" type="String" length="100"></property>
  </class>
</hibernate-mapping>

As you can see I've pre-filtered all my customers with this clause: ANFCLI = 'Y' Everything works perfectly fine if I query customers (the where clause is used):

var customers = session.QueryOver<Domain.Customer>()
    .Where(t => t.Company == "ABC01")
    .List();

But if I query the orders table - where I've got a many-to-one association:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly" namespace="MyAssembly.Domain">
  <class name="Order" table="OCSAORH" mutable="false" where="OCHAMND = 0">
    <composite-id>
      <key-property name="Number" column="OCHORDN" type="String" length="10"></key-property>
      <key-property name="Ver" column="OCHAMND" type="Int32"></key-property>
      <key-property name="Company" column="OCHCOSC" type="String" length="5"></key-property>
    </composite-id>

   <many-to-one name="Customer" class="Customer" lazy="proxy" fetch="join">
      <column name="OCHCLII" not-null="true"/>
      <column name="OCHCOSC" not-null="true"/>
    </many-to-one>
  </class>
</hibernate-mapping>

the filter on the entity customers is lost.
I was reading somewhere that the where clause doesn't work on a association and you have to use a where clause on the collection (bag, set, etc etc) but, how can I do that with a many-to-one?

Thanks for you help.

Was it helpful?

Solution

What about mapping Customer using a discriminator using ANFCLI and then setting the discriminator value to 'Y'. I think NHibernate will treat this a little more rigourously than a where clause.

<class name="Customer" table="ANSADID" mutable="false" discriminator-value="Y">
  <composite-id>
    <key-property name="CustomerCode" column="ANCOCO" type="String" length="10" />
    <key-property name="Company" column="ANCOSO" type ="String" length="5" />
  </composite-id>
  <discriminator column="ANFCLI" />
  <property name="Name" column="ANINCO" type="String" length="100" />
</class>

OTHER TIPS

I think degorolls is right: You would need to have a super class called "Person", and two sub types called "Customer" and "Supplier". Then you set your mapping so it uses the ANFCLI field as a discriminator, with the Y value for Customer and the N value for Supplier. This way, you'll have a nice and transparent polymorphism. (you'll be able to do stuff like "from Customer", or "from Supplier", and that will automagicaly add the where clause).

Hope that helps!

I'm also a newbie using NHibernate but perhaps you can map that relation (Order to Customer) using a bag (as if it would be one to many)!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top