Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quarkus JPA does not seem to apply EntityGraph hints #12980

Closed
dhoffer opened this issue Oct 27, 2020 · 11 comments · Fixed by #13352
Closed

Quarkus JPA does not seem to apply EntityGraph hints #12980

dhoffer opened this issue Oct 27, 2020 · 11 comments · Fixed by #13352
Labels
area/hibernate-orm Hibernate ORM kind/bug Something isn't working
Milestone

Comments

@dhoffer
Copy link

dhoffer commented Oct 27, 2020

Our entities use JPA @NamedEntityGraph to provide JPA hints on what should be included in the queries. Quarkus appears to be ignoring these hints so the query does not contain all the expected data. This causes LazyInitializationException to be thrown during object serialization because the data was not included in the fetch.

Here is an example of the entities.

@NamedEntityGraph(
                name = "Users.graph.detail",
                attributeNodes =
                        {
                                @NamedAttributeNode(value = "dataOwnerUsersCollection", subgraph = "dataOwnerUsersCollection"),
                                @NamedAttributeNode(value = "userControlCollection", subgraph = "userControlCollection")
                        })

Here is an example of the JPA query using the above EntityGraph.

public T find(IRequestContext requestContext, Object id, Class clazz) {
              
	Map<String, Object> hints = new HashMap<>();
	EntityManager e = requestContext.getEntityManager();
	List<EntityGraph<? super T>> graphs = e.getEntityGraphs(clazz);
	for (EntityGraph<?> graph : graphs) {
		if (graph.getName().contains(".detail")) {                
			hints.put("javax.persistence.loadgraph", graph);
			break;
		}
	}
	T t = (T) e.find(clazz, id, hints);
	if (t == null) {
		throw new NotFoundException();
	}

	return t;        
}

Quarkus v1.8.3.Final

openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)

@dhoffer dhoffer added the kind/bug Something isn't working label Oct 27, 2020
@famod famod added the area/hibernate-orm Hibernate ORM label Oct 27, 2020
@famod
Copy link
Member

famod commented Oct 27, 2020

/cc @Sanne

@gsmet
Copy link
Member

gsmet commented Oct 28, 2020

@dhoffer could you prepare a minimal reproducer in the form of a Maven project?

@dhoffer
Copy link
Author

dhoffer commented Oct 28, 2020

@gsmet Unfortunately I don't know how to do that, my project is huge and assumes the DB exists/etc.

@famod
Copy link
Member

famod commented Oct 28, 2020

@dhoffer There is a simple hibernate-orm quickstart that could be extended rather easily: https://github.com/quarkusio/quarkus-quickstarts/tree/master/hibernate-orm-quickstart
This Quickstart already comes with the necessary infrastructure (e.g. containerized PostgreSQL database).

@dhoffer
Copy link
Author

dhoffer commented Oct 28, 2020

@famod I am attempting to produce the reproducer starting with the quickstart you mentioned. Not there yet, but trying.

@dhoffer
Copy link
Author

dhoffer commented Nov 3, 2020

@famod @gsmet
Okay I was finally able to find the cause of this bug. It's a pretty strange one it seems to me.

Here is what it takes to reproduce this issue:

  • Create an Entity that has a Set/Collection using @onetomany (defaults to Lazy fetch)
  • Create an @NamedEntityGraph that will configure the above field to be @NamedAttributeNode (this will tell hibernate to fetch this in the select using join (to avoid N+1 issue).
  • Create a findById JPA method that uses a 'javax.persistence.loadgraph' NamedEntityGraph hint
  • In your application config (I used yaml) set quarkus.hibernate-orm.fetch.batch-size to anything other than the default (-1)
  • Run the findByID query and inspect the SQL written to the console. It should contain 'left outer join' per the

Per your suggestion I have modified the hibernate-orm-quickstart module to do the above and I changed the single test to test the above with a failing unit test.

I forked to the following. Should I create a PR for you to see changes? What is the best way to show you the new code & failing test?

https://github.com/dhoffer/quarkus-quickstarts

I created quarkusio/quarkus-quickstarts#704 so you can see a reproducer.

The bug is that quarkus.hibernate-orm.fetch.batch-size should have no effect on the hint provided and corresponding optimized join select statement.

@gsmet
Copy link
Member

gsmet commented Nov 3, 2020

@Sanne this looks like an issue in Hibernate ORM? I don't see how it could be Quarkus-related?

@Sanne
Copy link
Member

Sanne commented Nov 4, 2020

@gsmet I agree, we need to check if this works in Hibernate ORM vanilla.

Need to find a volunteer in the ORM team to investigate that.

@dhoffer many thanks for the reproducer, that's very useful.

@NathanQingyangXu
Copy link

I investigated ending up with the following two discoveries:

  1. There is a bug in Hibernate v5 that 'padding' batch style will ignore entity graph semantic;
  2. Hibernate ORM's batch style is 'legacy' by default but it seems the default value is 'padding' in this repo; not sure it is from Quarkus default setting?

@gsmet
Copy link
Member

gsmet commented Nov 4, 2020

@NathanQingyangXu I confirm we enforce the padded batching in Quarkus.

@NathanQingyangXu
Copy link

NathanQingyangXu commented Nov 4, 2020

Ticket was created here: https://hibernate.atlassian.net/browse/HHH-14312.
As a temporary fix, we might specify legacy batching style to make the testing case green.

@ghost ghost added this to the 1.11 - master milestone Nov 18, 2020
@gsmet gsmet modified the milestones: 1.11 - master, 1.10.0.Final Nov 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/hibernate-orm Hibernate ORM kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants