Top 30 Cannot Simultaneously Fetch Multiple Bags Best 232 Answer

You are looking for information, articles, knowledge about the topic nail salons open on sunday near me cannot simultaneously fetch multiple bags on Google, you do not find the information you need! Here are the best content compiled and compiled by the https://chewathai27.com/to team, along with other related topics such as: cannot simultaneously fetch multiple bags cannot simultaneously fetch multiple bags c#, Cannot simultaneously fetch multiple bags NHibernate, Join fetch multiple tables, Failed to lazily initialize a collection of role, FetchType lazy not working, LazyCollection, JOIN FETCH, Unable to evaluate the expression Method threw ‘org hibernate LazyInitializationException exception


Aula 10 – Aprenda a tratar o erro ‘cannot simultaneously fetch multiple bags’
Aula 10 – Aprenda a tratar o erro ‘cannot simultaneously fetch multiple bags’


java – Hibernate throws MultipleBagFetchException – cannot simultaneously fetch multiple bags – Stack Overflow

  • Article author: stackoverflow.com
  • Reviews from users: 48980 ⭐ Ratings
  • Top rated: 4.9 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about java – Hibernate throws MultipleBagFetchException – cannot simultaneously fetch multiple bags – Stack Overflow You can do the following trick: List posts = entityManager .createQuery( “select distinct p ” + “from Post p ” + “left join fetch p.comments ” + “where p. …
  • Most searched keywords: Whether you are looking for java – Hibernate throws MultipleBagFetchException – cannot simultaneously fetch multiple bags – Stack Overflow You can do the following trick: List posts = entityManager .createQuery( “select distinct p ” + “from Post p ” + “left join fetch p.comments ” + “where p.
  • Table of Contents:

18 Answers
18

The worst solution

The proper solution

There’s more you could do

Conclusion

Your Answer

Not the answer you’re looking for Browse other questions tagged java hibernate jpa one-to-many bag or ask your own question

java - Hibernate throws MultipleBagFetchException - cannot simultaneously fetch multiple bags - Stack Overflow
java – Hibernate throws MultipleBagFetchException – cannot simultaneously fetch multiple bags – Stack Overflow

Read More

The best way to fix the Hibernate MultipleBagFetchException

  • Article author: vladmihalcea.com
  • Reviews from users: 45194 ⭐ Ratings
  • Top rated: 5.0 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about The best way to fix the Hibernate MultipleBagFetchException MultipleBagFetchException: cannot simultaneously fetch multiple bags. In this article, we are going to see the reason Hibernate throws the … …
  • Most searched keywords: Whether you are looking for The best way to fix the Hibernate MultipleBagFetchException MultipleBagFetchException: cannot simultaneously fetch multiple bags. In this article, we are going to see the reason Hibernate throws the … Learn the best way to fix the Hibernate MultipleBagFetchException caused by fetching multiple List associations along with their parent entity.
  • Table of Contents:

Introduction

Domain Model

Hibernate throwing MultipleBagFetchException

How NOT to “fix” the Hibernate MultipleBagFetchException

How to fix the Hibernate MultipleBagFetchException

Conclusion

The best way to fix the Hibernate MultipleBagFetchException
The best way to fix the Hibernate MultipleBagFetchException

Read More

Your 2 best options to fix Hibernate’s MultipleBagFetchException

  • Article author: thorben-janssen.com
  • Reviews from users: 49630 ⭐ Ratings
  • Top rated: 4.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Your 2 best options to fix Hibernate’s MultipleBagFetchException Hibernate calls it a Bag, if the elements in your java.util. … MultipleBagFetchException: cannot simultaneously fetch multiple bags: [org.thoughts. on … …
  • Most searched keywords: Whether you are looking for Your 2 best options to fix Hibernate’s MultipleBagFetchException Hibernate calls it a Bag, if the elements in your java.util. … MultipleBagFetchException: cannot simultaneously fetch multiple bags: [org.thoughts. on … Your best option to fix Hibernate’s MultipleBagFetchException depends on your data structure. Here are your 2 best options and when to choose which of them.
  • Table of Contents:

Cause of the MultipleBagFetchException

Fixing the MultipleBagFetchException

Conclusion

Hibernate Tips How to avoid Hibernate’s MultipleBagFetchException

How to Choose the Most Efficient Data Type for To-Many Associations – Bag vs List vs Set

Common Hibernate Exceptions Every Developer Must Know

Hibernate Tips How to fetch associations in batches

Hibernate Tips How to map a bidirectional many-to-many association

Boost your Hibernate skills

Cheat Sheet10 Hibernate Mistakes That Cripple Your Performance

Your 2 best options to fix Hibernate's MultipleBagFetchException
Your 2 best options to fix Hibernate’s MultipleBagFetchException

Read More

Hibernate cannot simultaneously fetch multiple bags – Intellipaat Community

  • Article author: intellipaat.com
  • Reviews from users: 46038 ⭐ Ratings
  • Top rated: 3.4 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Hibernate cannot simultaneously fetch multiple bags – Intellipaat Community MultipleBagFetchException: cannot simultaneously fetch multiple bags. This is my test case: Parent.java. @Entity. public Parent {. …
  • Most searched keywords: Whether you are looking for Hibernate cannot simultaneously fetch multiple bags – Intellipaat Community MultipleBagFetchException: cannot simultaneously fetch multiple bags. This is my test case: Parent.java. @Entity. public Parent {. Hibernate throws this exception during SessionFactory creation: org.hibernate.loader.MultipleBagFetchException: … to Bozho for the solution).Java,java,jpa,hiberate,java-faq
  • Table of Contents:

Please log in or register to add a comment

Please log in or register to answer this question

1 Answer

Please log in or register to add a comment

Related questions

Popular Questions

Hibernate cannot simultaneously fetch multiple bags - Intellipaat Community
Hibernate cannot simultaneously fetch multiple bags – Intellipaat Community

Read More

Hibernate Orghibernateloadermultiplebagfetchexception Cannot Simultaneously Fetch Multiple Bags

  • Article author: www.faqcode4u.com
  • Reviews from users: 7387 ⭐ Ratings
  • Top rated: 4.9 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about
    Hibernate Orghibernateloadermultiplebagfetchexception Cannot Simultaneously Fetch Multiple Bags MultipleBagFetchException: cannot simultaneously fetch multiple bags. Tags: java , hibernate Answers: 1 | Viewed 15,379 times. Entity es. Customer. …
  • Most searched keywords: Whether you are looking for
    Hibernate Orghibernateloadermultiplebagfetchexception Cannot Simultaneously Fetch Multiple Bags MultipleBagFetchException: cannot simultaneously fetch multiple bags. Tags: java , hibernate Answers: 1 | Viewed 15,379 times. Entity es. Customer. Entity classes Customer @Entity @Table(name=”Custumer”) public class Custumer implements Serializable { @…
  • Table of Contents:

Hibernate orghibernateloaderMultipleBagFetchException cannot simultaneously fetch multiple bags

Answers

Some Code Answers

More Answers Related Hibernate Orghibernateloadermultiplebagfetchexception Cannot Simultaneously Fetch Multiple Bags


                    Hibernate Orghibernateloadermultiplebagfetchexception Cannot Simultaneously Fetch Multiple Bags
Hibernate Orghibernateloadermultiplebagfetchexception Cannot Simultaneously Fetch Multiple Bags

Read More


See more articles in the same category here: https://chewathai27.com/to/blog.

Hibernate throws MultipleBagFetchException – cannot simultaneously fetch multiple bags

Considering we have the following entities:

And, you want to fetch some parent Post entities along with all the comments and tags collections.

If you are using more than one JOIN FETCH directives:

List posts = entityManager .createQuery( “select p ” + “from Post p ” + “left join fetch p.comments ” + “left join fetch p.tags ” + “where p.id between :minId and :maxId”, Post.class) .setParameter(“minId”, 1L) .setParameter(“maxId”, 50L) .getResultList();

Hibernate will throw the infamous:

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags [ com.vladmihalcea.book.hpjp.hibernate.fetching.Post.comments, com.vladmihalcea.book.hpjp.hibernate.fetching.Post.tags ]

Hibernate doesn’t allow fetching more than one bag because that would generate a Cartesian product.

The worst “solution”

Now, you will find lots of answers, blog posts, videos, or other resources telling you to use a Set instead of a List for your collections.

That’s terrible advice. Don’t do that!

Using Sets instead of Lists will make the MultipleBagFetchException go away, but the Cartesian Product will still be there, which is actually even worse, as you’ll find out the performance issue long after you applied this “fix”.

The proper solution

You can do the following trick:

List posts = entityManager .createQuery( “select distinct p ” + “from Post p ” + “left join fetch p.comments ” + “where p.id between :minId and :maxId “, Post.class) .setParameter(“minId”, 1L) .setParameter(“maxId”, 50L) .setHint(QueryHints.PASS_DISTINCT_THROUGH, false) .getResultList(); posts = entityManager .createQuery( “select distinct p ” + “from Post p ” + “left join fetch p.tags t ” + “where p in :posts “, Post.class) .setParameter(“posts”, posts) .setHint(QueryHints.PASS_DISTINCT_THROUGH, false) .getResultList();

In the first JPQL query, distinct DOES NOT go to the SQL statement. That’s why we set the PASS_DISTINCT_THROUGH JPA query hint to false . DISTINCT has two meanings in JPQL, and here, we need it to deduplicate the Java object references returned by getResultList on the Java side, not the SQL side.

As long as you fetch at most one collection using JOIN FETCH , you will be fine.

By using multiple queries, you will avoid the Cartesian Product since any other collection but the first one is fetched using a secondary query.

There’s more you could do

If you’re using the FetchType.EAGER strategy at mapping time for @OneToMany or @ManyToMany associations, then you could easily end up with a MultipleBagFetchException .

You are better off switching from FetchType.EAGER to Fetchype.LAZY since eager fetching is a terrible idea that can lead to critical application performance issues.

Conclusion

Avoid FetchType.EAGER and don’t switch from List to Set just because doing so will make Hibernate hide the MultipleBagFetchException under the carpet. Fetch just one collection at a time, and you’ll be fine.

As long as you do it with the same number of queries as you have collections to initialize, you are fine. Just don’t initialize the collections in a loop, as that will trigger N+1 query issues, which are also bad for performance.

The best way to fix the Hibernate MultipleBagFetchException

Follow @vlad_mihalcea Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome? Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework. So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!

Introduction

If you’ve been using Hibernate for some time, there is a good chance you bumped into a MultipleBagFetchException issue:

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

In this article, we are going to see the reason Hibernate throws the MultipleBagFetchException as well as the best way to solve this issue.

Domain Model

Let’s consider that our application defines three entities: Post , PostComment , and Tag , which are associated as in the following diagram:

What we are mostly interested in this article is that the Post entity defines a bidirectional @OneToMany association with the PostComment child entity, as well as a unidirectional @ManyToMany association with the Tag entity.

@OneToMany( mappedBy = “post”, cascade = CascadeType.ALL, orphanRemoval = true ) private List comments = new ArrayList<>(); @ManyToMany( cascade = { CascadeType.PERSIST, CascadeType.MERGE } ) @JoinTable( name = “post_tag”, joinColumns = @JoinColumn(name = “post_id”), inverseJoinColumns = @JoinColumn(name = “tag_id”) ) private List tags = new ArrayList<>();

The reason why the @ManyToMany association cascades only the PERSIST and MERGE entity state transitions and not the REMOVE one is because the other side is not a child entity. Since the Tag entity lifecycle is not tied to the Post entity, cascading REMOVE or enabling the orphanRemoval mechanism would be a mistake. For more details about this topic, check out this article.

Hibernate throwing MultipleBagFetchException

Now, if we want to fetch the Post entities with the identifier values between 1 and 50, along with all their associated PostComment and Tag entities, we would write a query like the following one:

List posts = entityManager.createQuery(“”” select p from Post p left join fetch p.comments left join fetch p.tags where p.id between :minId and :maxId “””, Post.class) .setParameter(“minId”, 1L) .setParameter(“maxId”, 50L) .getResultList();

However, when running the entity query above, Hibernate throws a MultipleBagFetchException while compiling the JPQL query:

org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags [ com.vladmihalcea.book.hpjp.hibernate.fetching.Post.comments, com.vladmihalcea.book.hpjp.hibernate.fetching.Post.tags ]

So, no SQL query is executed by Hibernate. The reason why a MultipleBagFetchException is thrown by Hibernate is that duplicates can occur, and the unordered List , which is called a bag in Hibernate terminology, is not supposed to remove duplicates.

How NOT to “fix” the Hibernate MultipleBagFetchException

If you google the MultipleBagFetchException , you are going to see many wrong answers, like this one on StackOverflow, which, surprisingly, has over 280 upvotes.

So simple, yet so wrong!

Using Set instead of List

So, let’s change the association collection type from List to Set :

@OneToMany( mappedBy = “post”, cascade = CascadeType.ALL, orphanRemoval = true ) private Set comments = new HashSet<>(); @ManyToMany( cascade = { CascadeType.PERSIST, CascadeType.MERGE } ) @JoinTable( name = “post_tag”, joinColumns = @JoinColumn(name = “post_id”), inverseJoinColumns = @JoinColumn(name = “tag_id”) ) private Set tags = new HashSet<>();

And, now, when rerunning the previous entity query which fetched some Post entities along with their comments and tags associations, we can see that no MultipleBagFetchException is thrown.

However, this is SQL query that Hibernate executed for the aforementioned JPQL query:

SELECT p.id AS id1_0_0_, pc.id AS id1_1_1_, t.id AS id1_3_2_, p.title AS title2_0_0_, pc.post_id AS post_id3_1_1_, pc.review AS review2_1_1_, t.name AS name2_3_2_, pt.post_id AS post_id1_2_1__, pt.tag_id AS tag_id2_2_1__ FROM post p LEFT OUTER JOIN post_comment pc ON p.id = pc.post_id LEFT OUTER JOIN post_tag pt ON p.id = pt.post_id LEFT OUTER JOIN tag t ON pt.tag_id = t.id WHERE p.id BETWEEN 1 AND 50

So, what’s wrong with this SQL query?

The post and post_comment are associated via the post_id Foreign Key column, so the join produces a result set containing all post table rows with the Primary Key values between 1 and 50 along with their associated post_comment table rows.

The post and tag tables are also associated via the post_id and tag_id post_tag Foreign Key columns, so these two joins produce a result set containing all post table rows with the Primary Key values between 1 and 50 along with their associated tag table rows.

Now, to merge the two result sets, the database can only use a Cartesian Product, so the final result set contains 50 post rows multiplied by the associated post_comment and tag table rows.

So, if we have 50 post rows associated with 20 post_comment and 10 tag rows, the final result set will contain 10_000 records (e.g., 50 x 20 x 10), as illustrated by the following test case:

List posts = entityManager.createQuery(“”” select p from Post p left join fetch p.comments left join fetch p.tags where p.id between :minId and :maxId “””, Post.class) .setParameter(“minId”, 1L) .setParameter(“maxId”, 50L) .getResultList(); assertEquals( POST_COUNT * POST_COMMENT_COUNT * TAG_COUNT, posts.size() );

That’s so terrible from a performance perspective!

If you want to see how you can fix the MultipleBagFetchException when using Spring Data JPA, then check out this article.

How to fix the Hibernate MultipleBagFetchException

To avoid a Cartesian Product, you can fetch at most one association at a time. So, instead of executing a single JPQL query that fetches two associations, we can execute two JPQL queries instead:

List posts = entityManager.createQuery(“”” select distinct p from Post p left join fetch p.comments where p.id between :minId and :maxId”””, Post.class) .setParameter(“minId”, 1L) .setParameter(“maxId”, 50L) .setHint(QueryHints.PASS_DISTINCT_THROUGH, false) .getResultList(); posts = entityManager.createQuery(“”” select distinct p from Post p left join fetch p.tags t where p in :posts”””, Post.class) .setParameter(“posts”, posts) .setHint(QueryHints.PASS_DISTINCT_THROUGH, false) .getResultList(); assertEquals(POST_COUNT, posts.size()); for(Post post : posts) { assertEquals(POST_COMMENT_COUNT, post.getComments().size()); assertEquals(TAG_COUNT, post.getTags().size()); }

The first JPQL query defines the main filtering criteria and fetches the Post entities along with the associated PostComment records.

The PASS_DISTINCT_THROUGH query hint allows you to avoid passing the DISTINCT keyword to the SQL statement, and only use it to remove Java entity duplicates caused by the parent-child joined result set. For more details about the PASS_DISTINCT_THROUGH query hint, check out this article.

Now, we have to fetch the Post entities along with their associated Tag entities, and, thanks to the Persistence Context, Hibernate will set the tags collection of the previously fetched Post entities.

Cool, right?

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.

Conclusion

There are so many blog posts, videos, books, and forum answers, providing the wrong solution to the MultipleBagFetchException Hibernate issues. All these resources tell you that using a Set instead of a List is the right way to avoid this exception.

However, the MultipleBagFetchException tells you that a Cartesian Product might be generated, and, most of the time, that’s undesirable when fetching entities as it can lead to terrible data access performance issues.

The best way to fetch multiple entity collections with JPA and Hibernate is to load at most one collection at a time while relying on the Hibernate Persistence Context guarantee that only a single entity object can be loading at a time in a given JPA EntityManager or Hibernate Session .

Insert details about how the information is going to be processed DOWNLOAD NOW

Your 2 best options to fix Hibernate’s MultipleBagFetchException

Get access to all my video courses, 2 monthly Q&A calls, monthly coding challenges, a community of like-minded developers, and regular expert sessions.

Join the Persistence Hub!

You probably learned that you should use FetchType.LAZY for all of your associations. It ensures that Hibernate initializes an association when you use it and doesn’t spend any time getting data you don’t need.

Unfortunately, this introduces a new issue. You now need to use a JOIN FETCH clause or an EntityGraph to fetch the association if you need it. Otherwise, you will experience the n+1 select issue, which causes severe performance issues or a LazyInitializationException. If you do that for multiple associations, Hibernate might throw a MultipleBagFetchException.

In this article, I will explain when Hibernate throws this exception and show you your 2 best options to fix it. One of them is a great fit for associations with a small cardinality and the other one for associations that contain lots of elements. So, let’s take a look at both of them, and you pick the one that fits your application.

Cause of the MultipleBagFetchException

As I explained in a previous article about the most efficient data type for a to-many association, Hibernate’s internal naming of the collection types is pretty confusing. Hibernate calls it a Bag, if the elements in your java.util.List are unordered. If they are ordered, it’s called a List.

So, depending on your mapping, a java.util.List can be treated as a Bag or a List. But don’t worry, in real life, this isn’t as confusing as it might seem. Defining the order of an association requires an additional annotation and is almost always an overhead. That’s why you should avoid it and why at least 90% of the association mappings that use a java.util.List and that I’ve seen in real projects are unordered. So, Hibernate treats them as a Bag.

Here is a simple domain model in which Hibernate treats the Reviews and the Authors of a Book as Bags.

@Entity public class Book { @ManyToMany private List authors = new ArrayList(); @OneToMany(mappedBy = “book”) private List reviews = new ArrayList(); … }

If you try to fetch multiple of these bags in a JPQL query, you create a cartesian product.

TypedQuery q = em.createQuery(“SELECT DISTINCT b ” + “FROM Book b ” + “JOIN FETCH b.authors a ” + “JOIN FETCH b.reviews r ” + “WHERE b.id = 1”, Book.class); q.setHint(QueryHints.PASS_DISTINCT_THROUGH, false); List b = q.getResultList();

This can create performance problems. Hibernate also struggles to differentiate between information that is supposed to be duplicated and information that was duplicated because of the cartesian product. Because of that, Hibernate throws a MultipleBagFetchException.

java.lang.IllegalArgumentException: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [org.thoughts.on.java.model.Book.authors, org.thoughts.on.java.model.Book.reviews]

Fixing the MultipleBagFetchException

You can find lots of questions about this exception and various solutions to avoid it. But a lot of them come with unexpected side effects. The only 2 fixes between which you should choose are the ones that I will describe in the following sections. Which one of them is the best for you depends on the size of the cartesian product that your queries might create:

If all of your associations only contain a small number of elements, the created cartesian product will be relatively small. In these situations, you can change the types of the attributes that map your associations to a java.util.Set. Hibernate can then fetch multiple associations in 1 query. If at least one of your associations contains a lot of elements, your cartesian product will become too big to fetch it efficiently in 1 query. You should then use multiple queries that get different parts of the required result.

As always, optimizing the performance of your application requires you to choose between different trade-offs, and there is no one-size-fits-all approach. The performance of each option depends on the size of the cartesian product and the number of queries you’re executing. For a relatively small cartesian product, getting all information with 1 query provides you with the best performance. If the cartesian product reaches a certain size, you should better split it into multiple queries.

That’s why I will show you both options so that you can pick the one that fits your application.

Option 1: Use a Set instead of a List

The easiest approach to fix the MultipleBagFetchException is to change the type of the attributes that map your to-many associations to a java.util.Set. This is just a small change in your mapping, and you don’t need to change your business code.

@Entity public class Book { @ManyToMany private Set authors = new HashSet(); @OneToMany(mappedBy = “book”) private Set reviews = new HashSet(); … }

As explained earlier, if you now perform the same query as I showed you before to get the Book with all its Authors and Reviews, your result set will contain a cartesian product. The size of that product depends on the number of Books you select and the number of associated Authors and Reviews.

TypedQuery q = em.createQuery(“SELECT DISTINCT b ” + “FROM Book b ” + “JOIN FETCH b.authors a ” + “JOIN FETCH b.reviews r ” + “WHERE b.id = 1”, Book.class); q.setHint(QueryHints.PASS_DISTINCT_THROUGH, false); List b = q.getResultList();

Here you can see the generated SQL query. To get all the requested associations, Hibernate has to select all columns mapped by these entities. In combination with the cartesian product created by the 3 INNER JOINs, this can become a performance problem.

19:46:20,785 DEBUG [org.hibernate.SQL] – select book0_.id as id1_1_0_, author2_.id as id1_0_1_, reviews3_.id as id1_4_2_, book0_.publisherid as publishe5_1_0_, book0_.publishingDate as publishi2_1_0_, book0_.title as title3_1_0_, book0_.version as version4_1_0_, author2_.firstName as firstNam2_0_1_, author2_.lastName as lastName3_0_1_, author2_.version as version4_0_1_, authors1_.bookId as bookId1_2_0__, authors1_.authorId as authorId2_2_0__, reviews3_.bookid as bookid3_4_2_, reviews3_.comment as comment2_4_2_, reviews3_.bookid as bookid3_4_1__, reviews3_.id as id1_4_1__ from Book book0_ inner join BookAuthor authors1_ on book0_.id=authors1_.bookId inner join Author author2_ on authors1_.authorId=author2_.id inner join Review reviews3_ on book0_.id=reviews3_.bookid where book0_.id=1

Whenever you write such a query, you also need to keep in mind that Hibernate doesn’t hide that the result set contains a product. This query returns each Book multiple times. The number of references to the same Book object is calculated by the number of Authors multiplied by the number of Reviews. You can avoid that by adding the DISTINCT keyword to your select clause and by setting the query hint hibernate.query.passDistinctThrough to false.

Performance considerations

In this example, my query only selects 1 Book, and most Books have been written by 1-3 Authors. So, even if the database contains several Reviews for this Book, the cartesian product will still be relatively small.

Based on these assumptions, it might be faster to accept the inefficiency of the cartesian product to reduce the number of queries. This might change if your cartesian product becomes bigger because you select a huge number of Books or if your average Book has been written by a few dozen Authors.

Option 2: Split it into multiple queries

Fetching huge cartesian products in 1 query is inefficient. It requires a lot of resources in your database and puts unnecessary load on your network. Hibernate and your JDBC driver also need to spend more resources to handle the query result.

You can avoid that by performing multiple queries that fetch different parts of the required graph of entities. In the example of this post, I would fetch the Books with all their Authors in 1 query and the Books with all their Reviews in a 2nd query. If your graph of required entities is more complex, you might need to use more queries or fetch more associations with each of them.

TypedQuery q = em.createQuery(“SELECT DISTINCT b ” + “FROM Book b JOIN FETCH b.authors a ” + “WHERE b.id = 1”, Book.class); q.setHint(QueryHints.PASS_DISTINCT_THROUGH, false); List books = q.getResultList(); log.info(books.get(0)); q = em.createQuery(“SELECT DISTINCT b ” + “FROM Book b ” + “JOIN FETCH b.reviews r ” + “WHERE b.id = 1”, Book.class); q.setHint(QueryHints.PASS_DISTINCT_THROUGH, false); books = q.getResultList(); log.info(books.get(0)); log.info(“Authors: “+books.get(0).getAuthors().size()); log.info(“Reviews: “+books.get(0).getReviews().size());

As I explained in last week’s post, Hibernate ensures that within each Session, there is only 1 entity object that represents a specific record in the database. You can use that to resolve foreign key references efficiently or to let Hibernate merge the results of multiple queries.

If you take a look at the following log output, you can see that the Lists returned by both queries contain exactly the same object. In both cases, the Book objects have the reference @1f.

When Hibernate processed the result of the 2nd query, it checked for each record if the 1st level cache already contained an object for that Book entity. It then reused that object and added the returned Review to the mapped association.

19:52:10,600 DEBUG [org.hibernate.SQL] – select book0_.id as id1_1_0_, author2_.id as id1_0_1_, book0_.publisherid as publishe5_1_0_, book0_.publishingDate as publishi2_1_0_, book0_.title as title3_1_0_, book0_.version as version4_1_0_, author2_.firstName as firstNam2_0_1_, author2_.lastName as lastName3_0_1_, author2_.version as version4_0_1_, authors1_.bookId as bookId1_2_0__, authors1_.authorId as authorId2_2_0__ from Book book0_ inner join BookAuthor authors1_ on book0_.id=authors1_.bookId inner join Author author2_ on authors1_.authorId=author2_.id where book0_.id=1 19:52:10,633 INFO [org.thoughts.on.java.model.TestMultipleJoinFetch] – [email protected] 19:52:10,645 DEBUG [org.hibernate.SQL] – select book0_.id as id1_1_0_, reviews1_.id as id1_4_1_, book0_.publisherid as publishe5_1_0_, book0_.publishingDate as publishi2_1_0_, book0_.title as title3_1_0_, book0_.version as version4_1_0_, reviews1_.bookid as bookid3_4_1_, reviews1_.comment as comment2_4_1_, reviews1_.bookid as bookid3_4_0__, reviews1_.id as id1_4_0__ from Book book0_ inner join Review reviews1_ on book0_.id=reviews1_.bookid where book0_.id=1 19:52:10,648 INFO [org.thoughts.on.java.model.TestMultipleJoinFetch] – [email protected] 19:52:10,648 INFO [org.thoughts.on.java.model.TestMultipleJoinFetch] – Authors: 2 19:52:10,648 INFO [org.thoughts.on.java.model.TestMultipleJoinFetch] – Reviews: 2

Performance considerations

If you use multiple queries to get the required graph of entities, you avoid the creation of a huge cartesian product. This reduces the load on all involved systems and makes it easier to ensure a good performance for all queries.

But that not necessarily means that this approach is faster than option 1. You now perform more queries than before. Each of them requires a database roundtrip and creates some management overhead in the database, e.g., to create an execution plan. Due to that, this option is only faster than option 1, if the size of the cartesian product creates a bigger overhead than the execution of multiple queries.

Conclusion

As you have seen in this article, you can solve Hibernate’s MultipleBagFetchException in 2 ways:

So you have finished reading the cannot simultaneously fetch multiple bags topic article, if you find this article useful, please share it. Thank you very much. See more: cannot simultaneously fetch multiple bags c#, Cannot simultaneously fetch multiple bags NHibernate, Join fetch multiple tables, Failed to lazily initialize a collection of role, FetchType lazy not working, LazyCollection, JOIN FETCH, Unable to evaluate the expression Method threw ‘org hibernate LazyInitializationException exception

Leave a Comment