2010-05-07 14 views
10

Mam komponent zamapowany za pomocą Hibernuj. Jeśli wszystkie pola w komponencie w bazie danych są puste, sam składnik jest ustawiony na wartość null według stanu hibernacji. Jest to oczekiwane zachowanie, a także to, czego potrzebuję.pusta kolekcja hibernacji w komponencie

Problemem, który mam, jest to, że kiedy dodaję torbę do tego komponentu, torba jest inicjowana do pustej listy. Oznacza to, że komponent ma wartość niepustą ... powodującą utworzenie komponentu.

Każdy pomysł, jak to naprawić?

<class name="foo.bar.Entity" table="Entity"> 
<id name="id" column="id"> 
    <generator class="native" /> 
</id> 

<property name="departure" column="departure_time" /> 
<property name="arrival" column="arrival_time" /> 

<component name="statistics"> 
    <bag name="linkStatistics" lazy="false" cascade="all" > 
     <key column="entity_id" not-null="true" /> 
     <one-to-many class="foo.bar.LinkStatistics" /> 
    </bag> 

    <property name="loggedTime" column="logged_time" /> 

    ... 
</component> 

kryterium z Restirctions.isNull ("statystyki") nie zwraca oczekiwanych wartości.

+0

Proszę dodać informacje o kontekście: Kto ustawia składnik na wartość null? O którym komponencie mówisz? Który jest pojemnik? –

+0

Aaron, Hibernate pozostawia właściwość komponentu (statystyki, w klasie Jednostka) wartością null. –

+0

Wydaje się być dość starym problemem, ale mam go również i nie mogłem znaleźć żadnego rozwiązania. Czy w międzyczasie miałeś szczęście? – Martin

Odpowiedz

0

nie mogę zweryfikować to, ale mam pomysł:

public void setListProperty(List list) { 
    if (list == null || list.size() == 0) { 
    this.listProperty = null; 
    } else { 
    this.listProperty = list; 
    } 
} 

Oczywiście nie idealne, ale może być obejście dla Ciebie ...

+0

Czy to podejście naprawdę działa dla Ciebie? Z mojego doświadczenia wynika, że ​​takie sztuczki w seterach prowadzą do wyjątku "inna kolekcja jest już powiązana z sesją" w Hibernacji (ponieważ Hibernate zapamięta pustą kolekcję, którą zamierza powiązać z jednostką macierzystą). Tak więc powyższy kod zadziała, gdy jednostka zostanie odłączona (sesja, w której została załadowana, została zamknięta), ale w przeciwnym razie nie. Używanie 'null' w getter jest znacznie lepsze :) –

1

Podstawowym problemem jest to, że nie można odróżnić Hibernate między kolekcjami pustymi i pustymi kolekcjami, więc traktuje je jako puste: nie-puste.

Proponuję zamiast tego zmienić swój komponent Statystyka na rzeczywisty obiekt. Następnie twoja klasa foo.bar.Entity ma odwołanie, które może mieć wartość null. Nie jest to idealne rozwiązanie, ponieważ będziesz musiał stworzyć kolejną tabelę do przechowywania jednostki Statystyka, ale jeśli chcesz null vs puste rozróżnienie semantyczne, jest to sposób, aby go uzyskać.

+0

Poprawnie. Koncepcja kolekcji tak naprawdę nie istnieje w RDBMS, więc Hibernate (lub jakikolwiek ORM) musi to zrobić * coś *. –

0

Może to pomoże. Nie rozwiązuje problemu rozróżniania między pustą i pustą torbą, ale jest obejściem problemu. Jak być może wiesz, możesz wprowadzić przechwytywacz do sesji, który może przechwycić pewne akcje, takie jak zapisywanie lub aktualizowanie elementów, wtedy możesz użyć tego przechwytywacza, by sprawdzić stan komponentu, a jeśli jest pusty, ponownie go wyzeruj, aby wygrać hibernację Zapisuje puste wartości. here - Dokumenty.