1

I want to initialize a collection with lazy fetch mode and use Join Fetch in my queries but I some times(not always) face with lazy initialization exception ???

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: xxx.entity.Product.producerEntities, could not initilaize proxy - no session ...

for example this query:

"select p from Product p left join fetch p.producerEntities"

and my persistence class:

    class Product
    {
        Set<Producer> producerEntities = new HashSet<>();
        ....
        @OneToMany(fetch = FetchType.LAZY)
        @JoinColumn(name="pid")
        public Set<Producer> getProducerEntities(){
         return producerEntities;
         }
    ....

}

I don't understand what is the problem?

Cœur
  • 32,421
  • 21
  • 173
  • 232
M2E67
  • 818
  • 7
  • 21

4 Answers4

0

If join fetch is throwing LIEX then i could suggest use Dynamic Entity Graph, because if you need to define a use case specific graph.

Lets try this one, i did and work for me.

public class DynamicEntityGraphDemo {

    public static void main(String[] args) {

        EntityManager em = HibernateUtil.getEntityManager();
        EntityGraph graph = em.createEntityGraph(Product.class);
        Subgraph itemGraph = graph.addSubgraph("producerEntities");

        Map hints = new HashMap();
        hints.put("javax.persistence.loadgraph", graph);

        Product pro = em.find(Product.class, 1, hints);
        System.out.println("DynamicEntityGraphDemo pro  = " + pro.toString() + 
                 "producer =  " + pro.getProducerEntities().toString());
    }
}

NOTE : Dynamic Entity Graph uses LEFT OUTER JOIN while retrieving child entity. (Subgraph itemGraph = graph.addSubgraph("producerEntities");)

Angad Bansode
  • 619
  • 4
  • 13
0

join fetch p.producerEntities, not p.producer..

Christopher
  • 345
  • 2
  • 9
0

Problem was from my collection setter and getter methods name. It issolved.

M2E67
  • 818
  • 7
  • 21
0

there are many ways to solve, using hibernate properties

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
    return dataSource;
}

@Bean
public LocalSessionFactoryBean getSessionFactory() throws IOException {
    LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
    factoryBean.setDataSource(dataSource()); 

    Properties hibernateProperties = new Properties(); 
    hibernateProperties.setProperty("hibernate.enable_lazy_load_no_trans", "true"); 
    factoryBean.setHibernateProperties(hibernateProperties);
    factoryBean.afterPropertiesSet();

    return factoryBean;
}

@Bean
public HibernateTransactionManager getTransactionManager() throws IOException {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(getSessionFactory().getObject());
    return transactionManager;
}

or you can use

org.hibernate.annotations.@Proxy 

@Entity
@Table(name = "ACTOR")
@Proxy(lazy = false)
public class Actor 
Tiago Medici
  • 1,030
  • 12
  • 13
  • "hibernate.enable_lazy_load_no_trans" is considered an anti-pattern as is eager loading with n+1 queries. The whole point of FetchType.LAZY and JOIN FETCH is to address this. – Dave Apr 27 '21 at 01:20