2016-05-05 12 views
5

Questo è il mio soggetto:Hibernate ignora fetchgraph

public class PersonItem implements Serializable{ 
    @Id 
    @Column(name="col1") 
    private String guid; 

    @Column(name="col2") 
    private String name; 

    @Column(name="col3") 
    private String surname; 

    @Column(name="col4") 
    private Date birthDate; 
//+getters and setters 
} 

Questo è come ottenere l'elenco delle persone:

Query query = em.createQuery("Select p from PersonItem p WHERE p.guid IN (:guids)"); 
EntityGraph<PersonItem> eg = em.createEntityGraph(PersonItem.class); 
eg.addAttributeNodes("guid"); 
eg.addAttributeNodes("name"); 
eg.addAttributeNodes("surname"); 
query.setHint("javax.persistence.fetchgraph", eg); 
query.setParameter("guids", guids); 
List<PersonItem> list=query.getResultList(); 
em.close(); 
// And now I iterate result AFTER EM CLOSE 
....iterate 

Se ho capito prendere grafico correcly deve caricare solo quei campi, che ho specificato. Tuttavia, viene caricato anche il campo "birthDate". Inoltre vedo che in hibernate sql query 4 colonne sono selezionate.

Come ripararlo? Io uso Hibernate 5.1.0 come provider JPA.

risposta

5

I grafici di entità sono pensati per controllare quali relazioni (ad esempio, uno a uno, uno a molti, ecc.) Vengono caricate pigramente o con impazienza. Potrebbero non funzionare per il caricamento di singole colonne (dipende dal provider).

Hibernate ha qualche supporto per questo, ma è abbastanza difficile da funzionare, descritto here. Tuttavia, menzionano la seguente reticenza verso questo approccio (che sono pienamente d'accordo):

Si prega di notare che questo è principalmente un elemento di marketing; L'ottimizzazione delle letture della riga è molto più importante dell'ottimizzazione delle letture delle colonne.

Quindi non vi consiglio di andare troppo lontano su questa strada fino a quando hai confermato che questo è davvero un collo di bottiglia nella vostra applicazione (per esempio questo tipo di recuperare sintonizzazione può essere un sintomo di ottimizzazione prematura).

UPDATE:

Come sottolineato, APP vuol lasciarlo fino al provider come o meno semplici colonne (non-associazioni) sono pigramente inverosimile.

La strategia EAGER è un requisito sul provider di persistenza runtime che i dati devono essere avidamente inverosimile. La strategia LAZY è un suggerimento per il runtime del provider di persistenza che i dati devono essere recuperati pigramente al primo accesso. L'implementazione è consentita per i dati per i quali è stato richiesto il suggerimento della strategia LAZY è stato specificato. In particolare, il recupero pigro potrebbe essere disponibile solo per i mapping di base per i quali viene utilizzato l'accesso basato su proprietà.

A partire da Hibernate 5, è stato aggiunto il supporto ufficiale per il miglioramento del codice byte e questo potrebbe consentire il recupero di attributi pigri.

Dal latest Hibernate docs abbiamo:

2.3.2

fetch - fetchType (default) EAGER

definisce se questo attributo dovrebbe essere presa con entusiasmo o pigramente. JPA dice che EAGER è un requisito per il provider (Hibernate) che il valore deve essere recuperato quando il proprietario viene recuperato, mentre LAZY è solo un suggerimento che il valore essere recuperato quando l'attributo è accesso.Hibernate ignora questa impostazione per i tipi di base a meno che tu non stia utilizzando il potenziamento bytecode per .

E questo frammento successivo che descrive i vantaggi del miglioramento del bytecode.

attributo pigro loading

pensare a questo supporto di carico come parziale. In sostanza, è possibile dire allo Hibernate che solo le parti di un'entità devono essere caricate su che preleva dal database e quando l'altra parte deve essere caricata anche . Si noti che questo è molto diverso dall'idea basata su proxy di caricamento lazy che è incentrata sull'entità in cui lo stato dell'entità è caricato in una volta secondo necessità. Con l'ottimizzazione bytecode, i singoli attributi o gruppi di attributi vengono caricati secondo necessità.

+0

Il collegamento fornito sulla versione ibernata 3.3. Forse le cose sono cambiate da quel momento? –

+0

Puoi commentare questa risposta: http://stackoverflow.com/a/37053402/5057736. Lì l'uomo dice che questo codice funziona con un altro provider jpa e questo è secondo le specifiche JPA. –

+0

Può essere supportato se si utilizza l'ottimizzazione bytecode, inoltre, la mia risposta è specifica per Hibernate. Sono d'accordo che le specifiche JPA affermano che un fornitore può adottare entrambi gli approcci. Aggiornerò con i riferimenti pertinenti degli ultimi documenti. – Pace