Hibernate 2 ° oggetti di cache di livello che sono pigri = false, si traducono in un default recuperano = si uniscono, si è documentata da nessuna parte?

StackOverflow https://stackoverflow.com/questions/1968767

Domanda

I verificarsi il seguente problema, apparentemente privi di documenti, e voglio capire se

  1. Ho fatto qualcosa di sbagliato
  2. Qualcuno verifica lo stesso problema?
  3. E 'davvero non è documentata da nessuna parte? o mi sono perso qualcosa?

Il comportamento è questo Si supponga il seguente mappatura

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar"/>
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

In primo luogo, come sfondo, Hibernate valore predefinito per il prendere attributo su una relazione molti-a-uno dovrebbe essere " selezionare ", questo è almeno quello che è documentata (aggiungerò il link qui quando mi trovo)

Tuttavia, questo è apparentemente vero solo se la classe di riferimento è pigro = "true"!

così apparentemente la mappatura di cui sopra si traduce in questo (perché è pigro Bar = "false"):

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

Ora, perché vorrei che essere un problema? invece di 2 seleziona, Sospensione caricherà il riferimento non pigro in una singola selezionate con il suo "padre" (carico Foo con barra in una singola selezione)

questo in realtà ha un senso, dal momento che l'oggetto non è pigro, perché non caricarlo?

La risposta è questa: che cosa succede se Bar è nella cache di 2 ° livello

?
<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    <cache usage="transactional" />
    ...
</class>

E la risposta è - non cambia nulla

A quanto pare si potrebbe supporre Hibernate è abbastanza intelligente per capire che oggetti di questo tipo non dovrebbero essere caricati, ma dal momento che il default recuperare è stato cambiato da selezionare per unirsi, Hibernate non avere una scelta (non è possibile partecipare a un vero e proprio tavolo con la cache di 2 ° livello, ancora)

in modo Hibernate fa quello che viene detto, e utilizza un join per recuperare un oggetto dal database in cui è già presente nella cache di 2 ° livello

La soluzione che ho trovato è quello di cambiare letteralmente la mappatura per andare a prendere = "selezionare"

Ora, quando la seconda selezione per Bar è in procinto di andare, Hibernate capisce non dovrebbe andare al database e recupera dalla cache. e solo 1 interrogazione verrà eseguita (dopo il riscaldamento)

È stato utile?

Soluzione

Ho incontrato lo stesso problema, e mi trovai marcatura tutti i molti-a-uno relazioni che verranno memorizzati nella cache come fetch="select". Nel momento in cui la query viene costruita, Hibernate non può sapere se l'istanza richiesta di Bar si trova nella seconda cache di livello o meno (supponendo che Foo non è nella cache).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top