| I new with hibernate and I tested n+1 query issue with different entity relations. I discovered, that not only some proposed solutions do not solve n+1 query issue, but also I encontered 2n+1 issue in bidirectional OneToOne mapping. I added maven project in attachments for issue reproduction. Project is also available on github: https://github.com/jowko/HibernateBug Theory: Imagine that you have two entities: Kennel and Dog. Both are related OneToOne with each other, so each Kennel can have only one Dog and vice versa. You want to show table for user with information about Dogs and Kennels, so you have to fetch all data eagerly. If you have 50 rows per page, you want to get all data in 1 query. When you execute such query:
entityManager.createQuery("from Kennel");
You would expect that you retrieve data in 51 queries(n+1 issue). But in such cases hibernate will generate 101 queries. First query will get list of all Kennels. Assuming that every Kennel has Dog, you get another 100 queries, 1 for each Kennel and Dog. It is extreamly inefficient. Undirected OneToOne relations or all OneToMany relations have n+1 issue in such case(but not 2n+1 issue). If you try to use fetch join, you will improve performance in most cases(n+1 issue will be solved with 1 query, but in ManyToMany relations it issue still exists). But 2n+1 issue will transform to n+1 issue. So such query:
entityManager.createQuery("from Kennel k join fetch k.dog");
Will give 51 queries instead of 1. Also first select will fetch all nedded data for both Kennels and Dogs, but hibernate still performs 50 queries to get Dog for each Kennel. I tested it on Oracle Express Edition. Don't know if it is Oracle specific problem or global. In example I also used Lombok, but this library din't changed anything in hibernate behavior. |