JPA - join selection in field using Root, Join

I have these classes, the fields are always lazy loaded.

public class Book {
     @ManyToOne(fetch = FetchType.LAZY)
     private Publication publication;

     @OneToMany(fetch = FetchType.LAZY)
     private List<Author> authors;

     @OneToMany(fetch = FetchType.LAZY)
     private List<Genre> genres;
}

public class Publication{
     @OneToMany(fetch = FetchType.LAZY)
     private List<Founder> founders;

}

      

What I am trying to achieve is a connection fetch connection. In hql it looks like this:

FROM Book b LEFT JOIN b.authors LEFT JOIN b.genres LEFT JOIN b.publication p LEFT JOIN p.founders

      

This is what I've tried so far, but it doesn't work:

Root<Book> root ...
Join<Book, Publication> publication = root.join("publication");
publication.fetch("founders");
root.fetch("authors");
root.fetch("genres");

      

Here's the reason for the exception:

Caused by: javax.persistence.PersistenceException: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:588)
    at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:336)
    at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:147)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:736)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)

      

+3


source to share


1 answer


The JPA spec says:

Multiple levels of sampling connections shall not be supported complying with this specification. Applications that use tiered pull connections will not be portable.

Try decreasing the samples from the query and initializing the data later (after selecting the data). You can initialize lazy loaded data using size () or Hibernate.initialize () in the same transaction, for example:



publication.getFounders().size();

      

or

Hibernate.initialize(publication.getFounders());

      

+6


source







All Articles