2009-11-03 12 views
17

Udało mi się napisać system zawierający zamówienie z liniami zamówień podrzędnych, używając aktualizacji kaskadowych z zamówienia, aby zapisać wiersze zamówienia. W następnej iteracji chcę powiązać linie zamówienia z klasą wysyłki. Wydawało się to całkiem proste - dodaj tabelę DespatchID zerową do tabeli wierszy zamówienia jako klucz foriegn do tabeli Despatch. Jednak, gdy dodaję to do mapowania i zapisz obiekt zamówienia z komunikatami, które nie są ustawione w wierszach zlecenia, otrzymam błąd "obiekt odwołuje się do niezapisanej instancji przejściowej - zapisz instancję przejściową przed opróżnieniem".Błąd NHibernate - Zapisz przejściową instancję przed wypłukaniem

Po usunięciu powiązania między linią zamówienia a wysyłką, zapisuje się OK. Mogę tylko założyć, że błąd jest spowodowany, ponieważ próbuje zapisać wysyłkę, która nie istnieje.

Oto mapowania (klasa linie zamówienie jest nazywane OrderProductAmount):

<class name="NHS.WebTeam.PandemicFluDistribution.Order, NHS.WebTeam.PandemicFluDistribution" table="[Order]" lazy="false" optimistic-lock="version" where="Deleted=0" > 
    <id name="ID" type="Int32" column="OrderID" unsaved-value="0"> 
     <generator class="hilo"> 
     <param name="table">NHibernateHiLo</param> 
     <param name="column">NextValue</param> 
     <param name="max_lo">100</param> 
     </generator> 
    </id> 

    <version column="version" name="Version"/> 
    <property name="Deleted" column="Deleted" /> 

    <property name="DateEntered"></property> 
    <property name="RequiredDeliveryDate"></property> 

    <many-to-one name="Practice" column="PracticeID"></many-to-one> 

    <set name="OrderProductAmounts" access="field.camelcase-underscore" inverse="true" cascade="all-delete-orphan" lazy="true"> 
     <key column="OrderID"></key> 
     <one-to-many class="NHS.WebTeam.PandemicFluDistribution.OrderProductAmount, PandemicFluDistribution" /> 
    </set> 

    </class> 

    <class name="NHS.WebTeam.PandemicFluDistribution.OrderProductAmount, NHS.WebTeam.PandemicFluDistribution" table="OrderProductAmount" lazy="false" optimistic-lock="version" where="Deleted=0" > 
    <id name="ID" type="Int32" column="OrderProductAmountID" unsaved-value="0"> 
     <generator class="hilo"> 
     <param name="table">NHibernateHiLo</param> 
     <param name="column">NextValue</param> 
     <param name="max_lo">100</param> 
     </generator> 
    </id> 

    <version column="version" name="Version"/> 
    <property name="Deleted" column="Deleted" /> 

    <many-to-one name="Order" column="OrderID"></many-to-one> 
    <many-to-one name="ProductAmount" column="ProductAmountID"></many-to-one> 
    <many-to-one name="Despatch" column="DespatchID" cascade="none" not-null="false"></many-to-one> 
    </class> 

    <class name="NHS.WebTeam.PandemicFluDistribution.Despatch, NHS.WebTeam.PandemicFluDistribution" table="Despatch" lazy="false" optimistic-lock="version" where="Deleted=0" > 
    <id name="ID" type="Int32" column="DespatchID" unsaved-value="0"> 
     <generator class="hilo"> 
     <param name="table">NHibernateHiLo</param> 
     <param name="column">NextValue</param> 
     <param name="max_lo">100</param> 
     </generator> 
    </id> 

    <version column="version" name="Version"/> 
    <property name="Deleted" column="Deleted" /> 

    <property name="DateDespatched"></property> 
    <property name="RequiredDeliveryDate"></property> 

    <many-to-one name="Practice" column="PracticeID"></many-to-one> 

    <set name="OrderProductAmounts" access="field.camelcase-underscore" inverse="true" cascade="none" lazy="true"> 
     <key column="DespatchID"></key> 
     <one-to-many class="NHS.WebTeam.PandemicFluDistribution.OrderProductAmount, PandemicFluDistribution" /> 
    </set> 

    </class> 

Kod do tworzenia zamówienia jest zasadniczo to:

Dim practice = ... get relevant Practice ... 
Dim productAmount = ... get relevant ProductAmount ... 
Dim newOrder as Order = new Order(practice) 
newOrder.AddProductAmount(new OrderProductAmount(newOrder, productAmount) 
OrderDAO.Save(newOrder) 

Czy ktoś ma jakieś pomysły?

+1

Jestem pewien, że odwołujesz się tutaj do klasy wysyłki. Pokaż kod, w którym instancja jest tworzona lub ładowana i przechowywana ... –

+0

Dodałem przybliżenie kodu, który tworzy zamówienie na pytanie. Nie napisałem jeszcze kawałka, który dodaje rozesłanie do linii zamówienia, więc nie pomyślałbym, że jeszcze będzie między nimi związek. –

+2

Kiedy tworzysz obiekt Zamówienie, jaką wartość przypisujesz do właściwości Wysyłki? Jeśli nie jest to NULL, a zamiast tego jest obiektem Despatch z Id = 0, myślę, że NHibernate rzuci ten wyjątek. –

Odpowiedz

21

Jak sugerują powyższe komentarze (dla których wielkie dzięki), było coś, co nie brzmiało dobrze w kwestii wysyłki. I, jak się okazało, Despatch nie był problemem. Chociaż z jakiegoś powodu zadziałało, zanim dodałem go.

I rozwiązany problem przez dodanie kaskadę = „all” do łącza OrderProductAmount do Zakonu:

<many-to-one name="Order" column="OrderID" cascade="all"></many-to-one> 

Błąd, który został rzucony, że Zakon był jeszcze przemijający gdy OrderProductAmount był zapisany. Jest to bardzo mylące, ponieważ to Zamówienie, a nie kwota OrderProduct, którą oszczędzam - ZamówieniaProductAmounts są zapisywane tylko przez kaskadę z Orderu.

Tak więc, jeśli ktoś ma jakieś pomysły, dlaczego tak jest, chciałbym wiedzieć.

+2

Dzięki za podzielenie się swoją odpowiedzią. Dodanie .Cascade.All() do odniesienia do tabeli obcej rozwiązało dla mnie powyższy błąd. – iniki

Powiązane problemy