Hibernate ignores fetchgraph

This is my essence:

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 } 

This is how I get a list of people:

 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 

If I understand the selection graph correctly, it should only load the fields that I specified. However, the BirthDate field is also loaded. In addition, I see that 4 columns are selected in hibernate sql query.

How to fix it? I am using hibernate 5.1.0 as a JPA provider.

+5
source share
1 answer

Entity charts are designed to control which relationships (for example, one-to-one, one-to-many, etc.) are loaded lazily or impatiently. They may not work for loading individual columns (it depends on the provider).

Hibernate has some support for this, but it's pretty hard to get the job described here . However, they mention the following restraint regarding this approach (with which I completely agree):

Please note that this is mainly a marketing function; optimizing row reading is much more important than optimizing column reading.

Therefore, I would not recommend moving too far along this road until you confirm that this is really a bottleneck in your application (for example, such a sample setting may be a symptom of premature optimization).

UPDATE:

As already noted, JPA does not provide the provider with access to a lazy selection of simple columns (not associations).

The EAGER strategy is a prerequisite for the continuity provider that data should be received with impatience. The LAZY strategy is a hint at the runtime of the persistence provider that the data should be received lazily when it is first accessed. Implementation is permitted to readily retrieve data for which a hint of LAZY strategy has been indicated. In particular, lazy choices may only be available for Basic mappings that use property-based access.

Starting with Hibernate 5, official support for bytecode extension has been added, and this can provide a lazy attribute.

In the latest versions of Hibernate :

2.3.2

fetch - FetchType (default is EAGER)

Determines whether to retrieve this attribute impatiently or lazily. JPA says that EAGER is a requirement for the provider (Hibernate) that the value should be retrieved when the owner is retrieved, and LAZY is just a hint that the value will be retrieved when the attribute is accessed. Hibernate ignores this setting for base types unless you use bytecode gain.

And this next snippet that describes the benefits of improving bytecode.

Loading a lazy attribute

Think of it as a partial download. In fact, you can say Hibernate so that only part (s) of the object are fetched from the database and when loading another part (s) as well. Note that this is very different from the proxy-based idea of ​​lazy loading, which is essentially oriented when the subject state loads immediately as needed. Bytecode enhancement, individual attributes or attribute groups are loaded as needed.

+5
source

All Articles