Cosium / spring-data-jpa-entity-graph

Spring Data JPA extension allowing full dynamic usage of EntityGraph on repositories
MIT License
466 stars 51 forks source link

Using spring-data-jpa-entity-graph with Hibernate enhanced bytecode #34

Closed fistons closed 4 years ago

fistons commented 4 years ago

We have this kind of entity:

@Entity
public class Stuff {

 @Id
  private Integer id;

  @Lob
  @Basic(fetch = FetchType.LAZY)
  private byte[] data;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "other_id", referencedColumnName = "id", nullable = false)
  private OtherClass other;
}

To be able to lazily fetch the data column, we have to use the hibernate-enhance-maven-plugin with hibernate.enhancer.enableLazyInitialization=true

But, it looks like the entity graph magic stuff doesn't play well with it.

When we try to fetch all Stuff from database, we proceed like this:

Iterable<Stuff> stuffes =  repository.findAll(EntityGraphUtils.fromAttributePaths("other"));

In the hibernate log, we can see that the data field is not fetched as intended, but we see a SELECT request for each OtherClass, which is precisely what we tries to avoid by using the entity graph.

When we remove the hibernate-enhance-maven-plugin from the pom.xml, the entity graph works just fine, but the data column is always eagerly fetched.

We are not really sure if the issue comes from spring-data-jpa-entity-graph or from elsewhere, but maybe you have an idea of the source of the problem?

fistons commented 4 years ago

After further research, it looks like our issue is purely with HIbernate: https://hibernate.atlassian.net/browse/HHH-8776

reda-alaoui commented 4 years ago

Hi @fistons ,

I never used Hibernate with bytecode enhancement.

This library only appends the entity graph as a Query Hint to the query executed by Spring data. It does not care about the result returned by the query, so there is no post processing of the result that could trigger a subsequent query.

So I am pretty sure the behaviour you encounter is not caused by this project :)

I recommend you to try to call directly the EntityManager with an EntityGraph query hint to make sure of it.

fistons commented 4 years ago

Yes we found out after the issue creation that the culprit was Hibernate.

The only solution we found for the time being is to create another an Entity without our data and another with it, both linked to the same table, and requesting one or the other depending on what we need. This is ugly as hell, but it works.

Sorry for the noise, and thanks for your project!