Best way to model many-to-one relationships in NHibernate when working with an obsolete database?

Warning - I am very new to NHibernate. I know this question seems simple - and I'm sure there is a simple answer, but for a while I turned my wheels on it. I am dealing with an obsolete db that really cannot be changed structurally. I have a details table that lists the payment plans that have been accepted by the client. Each payment plan has an identifier that refers to a lookup table to get the terms of the plan, conditions, etc. In my object model, I have an AcceptedPlan class and a Plan class. I originally used many-to-one relationships from the details table back to the ref table to model these relationships in NHibernate. I also created a one-to-many relationship that goes in the opposite direction from the Plan class to the AcceptedPlan class.It was great when I just read the data. I could go to my Plan object, which was a property of the AcceptedPlan class, to read the details of the plan. My problem arose when I had to start inserting new rows into the details table. From my reading, it seems that the only way to create a new child is to add it to the parent and then save the session. But I do not want to create a new parent plan object every time I want to create a new detail record. This seems like unnecessary overhead. Does anyone know if I will do it wrong?From my reading, it seems that the only way to create a new child is to add it to the parent and then save the session. But I do not want to create a new parent plan object every time I want to create a new detail record. This seems like unnecessary overhead. Does anyone know if I will do it wrong?From my reading, it seems that the only way to create a new child is to add it to the parent and then save the session. But I do not want to create a new parent plan object every time I want to create a new detail record. This seems like unnecessary overhead. Does anyone know if I will do it wrong?

+3
source share
6 answers

I would avoid having a child object containing their logical parent, it can become very dirty and very recursive pretty quickly when you do this. I would see how you are going to use the domain model before doing something like this. You can easily get links to identifiers in tables and just leave them unchanged.

Here are two examples of mappings that might push you in the right direction, I had to give table names, etc., but that could help. I would also suggest mapping StatusId to enumeration.

Pay attention to how the bag effectively matches the detail table with the collection.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
    <class lazy="false" name="Namespace.Customer, Namespace" table="Customer">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="CustomerAccountId" length="4" sql-type="int" not-null="true" unique="true" index="CustomerPK"/>
            <generator class="native" />
        </id>

        <bag name="AcceptedOffers" inverse="false" lazy="false" cascade="all-delete-orphan" table="details">
          <key column="CustomerAccountId" foreign-key="AcceptedOfferFK"/>
          <many-to-many
            class="Namespace.AcceptedOffer, Namespace"
            column="AcceptedOfferFK"
            foreign-key="AcceptedOfferID"
            lazy="false"
           />
        </bag>

  </class>
</hibernate-mapping>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
    <class lazy="false" name="Namespace.AcceptedOffer, Namespace" table="AcceptedOffer">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="AcceptedOfferId" length="4" sql-type="int" not-null="true" unique="true" index="AcceptedOfferPK"/>
            <generator class="native" />
        </id>

        <many-to-one 
          name="Plan"
          class="Namespace.Plan, Namespace"
          lazy="false"
          cascade="save-update"
        >
        <column name="PlanFK" length="4" sql-type="int" not-null="false"/>
        </many-to-one>

        <property name="StatusId" type="Int32">
            <column name="StatusId" length="4" sql-type="int" not-null="true"/>
        </property>

  </class>
</hibernate-mapping>
+3
source

Did not see the database diagram at the time of writing.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
    <class lazy="false" name="Namespace.Customer, Namespace" table="Customer">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="customer_id" length="4" sql-type="int" not-null="true" unique="true" index="CustomerPK"/>
            <generator class="native" />
        </id>

        <bag name="AcceptedOffers" inverse="false" lazy="false" cascade="all-delete-orphan">
            <key column="accepted_offer_id"/>
            <one-to-many class="Namespace.AcceptedOffer, Namespace"/>
        </bag>

  </class>
</hibernate-mapping>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
    <class lazy="false" name="Namespace.AcceptedOffer, Namespace" table="Accepted_Offer">
        <id name="Id" type="Int32" unsaved-value="0">
            <column name="accepted_offer_id" length="4" sql-type="int" not-null="true" unique="true" />
            <generator class="native" />
        </id>

        <many-to-one name="Plan" class="Namespace.Plan, Namespace" lazy="false" cascade="save-update">
            <column name="plan_id" length="4" sql-type="int" not-null="false"/>
        </many-to-one>

  </class>
</hibernate-mapping>

, ( , ).

+1

, , :

ICollection <PaymentPlan> PaymentPlans, , .

PaymentPlan , , , . all-delete-orphan, , , PaymentPlans, , .

PaymentPlan PlanTerms, .

PlanTerms -, PlanTerms PaymentPlan.

, PlanTerms , , PaymentPlan , PaymentPlan, PlanTerms, . , nhibernate .

Customer, PaymentPlan PlanTerms Customer (Customer table), PaymentPlans ( ), PlanTerms ( ).

, , , , , , - .

0

, - , NHibernate , BaseDetail, , Detail.

, BaseDetail, Parent Plan, BaseDetail, Detail PlanId, , Detail.

, , , .

0

, , , , AcceptedOffer Plan, Plan AcceptedOffers, AcceptedOffer. . , , , .

, AcceptedOffer : , , . .

, , , , . , :

  • , , , - OfferId Plan, , .
  • Plan, Offers ( ).
  • , AcceptedOffer , , . .

I think that it will be enough to unravel your NHibernate mappings and problems with saving objects. :)

0
source

A tip that may (or may be) useful in NHibernate: you can map your objects to views as if the View were a table. Just specify the view name as the table name; as long as all NOT NULL fields are included in the view and the display will work fine.

0
source

Source: https://habr.com/ru/post/1696415/


All Articles