Hibernate Molti-To-One chiave esterna di default 0
-
10-10-2019 - |
Domanda
Ho una tabella in cui l'oggetto il genitore ha un rapporto opzionale molti-a-uno. Il problema è che la tabella è configurato di default la colonna Fkey a 0.
Quando si seleziona, utilizzando prendere = "join", etc-- il valore predefinito di 0 sul Fkey viene utilizzato per provare più e più volte per selezionare da un altro tavolo per l'ID 0. Naturalmente questo non esiste, ma come posso dire a Hibernate per il trattamento di un valore da 0 a essere la stessa di NULL-- di non passare da 20 + volte il recupero di un rapporto che non esiste?
<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"/>
Soluzione 2
Sono stato in grado di risolvere questo problema con la creazione di un tipo di id-lunga che si estende il costruito nel tipo lungo, ma se l'id tornato da SQL è stata dello 0, ritorno null al suo posto. Ciò ha mantenuto l'indennità di 0 di default nel nostro DB mentre ottenere ibernazione di smettere di fare recuperi pigri.
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);
}
}
}
La ragione di far rispettare esplicita default 0 è che le maniglie Oracle indicizzazione e valori nulli stranamente, suggerendo una migliore performance query con valori espliciti contro 'dove col è [non] null'
Altri suggerimenti
Ci sono due modi per farlo, il modo in cui si può ottenere brutto prestazioni-saggio e il modo in cui è doloroso e scomodo.
Il modo potenzialmente brutto è fatto sul fine Toone. Usando Hibernate annotazioni sarebbe:
@Entity
public class Foo
{
...
@ManyToOne
@JoinColumn( name = "DEVICEID" )
@NotFound( action = NotFoundAction.IGNORE )
private Device device;
...
}
Purtroppo, questo le forze di un successo di database preemptive (senza lazy loading) perché dispositivo può essere NULL, e se Hibernate creato un dispositivo pigro poi "dispositivo == null" non sarebbe mai essere vero.
L'altro modo consiste nel creare un UserType personalizzato che intercetta le richieste per l'ID 0 e restituisce NULL per loro, e poi assegnando che alla chiave primaria del dispositivo con @type. Questo forze interpretazione 0 ~ nulla su tutti con una chiave esterna nel dispositivo.
Penso che si sta utilizzando tipo primitivo come i vostri primario / colonne chiave esterna nell'oggetto. Se sì allora provare a utilizzare classi wrapper. Poiché i tipi primitivi non possono avere valori di default come null.