2011-01-13 12 views
6

Mam tabelę, w której obiekt nadrzędny ma opcjonalną relację wiele do jednego. Problem polega na tym, że w tabeli ustawiono domyślną kolumnę z kluczem na 0.Klawisz obcego klucza wieloznacznego Hibernuj Domyślnie 0

Podczas wybierania, za pomocą fetch = "join", itp. Domyślne ustawienie 0 na klawiaturze służy do wielokrotnego sprawdzania z innej tabeli dla ID 0. Oczywiście to nie istnieje, ale jak mogę powiedzieć Hibernate traktować wartość 0, aby była taka sama jak NULL - aby nie przechodzić przez 20+ razy podczas pobierania relacji, która nie robi nic T istniejesz?

<many-to-one name="device" lazy="false" class="Device" not-null="true" access="field" cascade="none" not-found="ignore"> 
<column name="DEVICEID" default="0" not-null="false"/> 

+0

Dlaczego jest domyślna wartość 0, a nie NULL? Ponadto FK musi mieć wartość NULL lub prawidłowy identyfikator w tabeli docelowej. Czy ta kolumna ma w rzeczywistości na sobie konstelację FK? – sblundy

Odpowiedz

2

Udało mi się to naprawić, tworząc typ id-long, który rozszerza wbudowany typ Long, ale jeśli identyfikator zwrócony z SQL miał wartość 0, zwróć wartość null. W ten sposób utrzymywało się wartość domyślna 0 w naszym DB podczas uzyskiwania hibernacji, aby przestać robić leniwy pobór.

public class IdentifierLongType extends LongType implements IdentifierType { 

@Override 
public Object get(ResultSet rs, String name) throws SQLException { 
    long i = rs.getLong(name); 
    if (i == 0) { 
     return null; 
    } else { 
     return Long.valueOf(i); 
    } 
} 

}

Powodem zapewniającą wyraźny domyślna 0 jest to, że Oracle obsługuje indeksowania i wartości zerowe dziwnie, co sugeruje lepszą wydajność kwerendy z jednoznacznych wartości kontra „gdzie col jest [Nie] null”

0

myślę używasz prymitywny typ jako podstawowy/klucz obcy kolumn w obiekcie. Jeśli tak, spróbuj użyć klas opakowania. Ponieważ typy pierwotne nie mogą mieć wartości domyślnych jako null.

3

Można to zrobić na dwa sposoby: sposób, w jaki można osiągnąć brzydki wzrost wydajności oraz sposób, który jest bolesny i niezręczny.

Potencjalnie brzydki sposób jest wykonywany na końcu ToOne. Korzystanie Hibernacja adnotacje byłoby:

@Entity 
public class Foo 
{ 
    ... 

    @ManyToOne 
    @JoinColumn(name = "DEVICEID") 
    @NotFound(action = NotFoundAction.IGNORE) 
    private Device device; 

    ... 
} 

Niestety, ten wymusza pierwszeństwa trafienie bazy danych (nie leniwy załadunku), ponieważ urządzenie może być null, a jeśli Hibernate stworzony leniwe Device następnie „urządzenie == null” nigdy nie będzie prawdziwe.

Innym sposobem jest utworzenie niestandardowego UserType, który przechwytuje żądania dla identyfikatora 0 i zwraca dla nich wartość null, a następnie przypisuje je do klucza podstawowego urządzenia za pomocą @Type. To wymusza interpretację 0 ~ null dla każdego z obcym kluczem do Urządzenia.

Powiązane problemy