Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate LazyInitializationException using Spring CrudRepository

I always get the exception:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.knapp.vk.domain.Business.businessCategorySet, could not initialize proxy - no Session

I don´t want to set fetch to eager. What would be other good solutions?

Business Entity class:

@Entity
public class Business
{
    @Id
    @GeneratedValue
    private int pk;

    @ManyToMany
    private Set<BusinessCategory> businessCategorySet = new HashSet<BusinessCategory>();

...
}

BusinessRepository interface:

import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public interface BusinessRepository extends CrudRepository<Business, Integer>
{

}

Config:

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories(basePackages = "com.knapp.vk.repositorynew")
@EnableTransactionManagement
public class JPAConfiguration
{
    @Bean
    public EntityManagerFactory entityManagerFactory() throws SQLException
    {
        return Persistence.createEntityManagerFactory("standardManager");
    }

    @Bean
    public EntityManager entityManager(EntityManagerFactory entityManagerFactory)
    {
        return entityManagerFactory.createEntityManager();
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws SQLException
    {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator()
    {
        return new HibernateExceptionTranslator();
    }
}
like image 839
oliverkn Avatar asked Dec 05 '25 12:12

oliverkn


1 Answers

Also you can add method in repository:

@Transactional(readOnly = true)
public List<Business> findAllEagerly() {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Business> query = builder.createQuery(Business.class);
    Root<Business> root = query.from(Business.class);
    root.fetch(Business_.businessCategorySet);
    return em.createQuery(query).getResultList();
}

or easier to use @Query in JpaRepository:

@Query("SELECT b FROM Business b JOIN FETCH b.businessCategorySet")
public List<Business> findAll();

I think good solution is to use @NamedEntityGraph

@Entity
@NamedEntityGraph(name = "Business.detail",
        attributeNodes = @NamedAttributeNode("businessCategorySet"))
public class Business {...}

and in Repository

public interface BusinessRepository extends CrudRepository<Business, Integer> {
    @EntityGraph(value = "Business.detail", type = EntityGraphType.LOAD)
    List<Business> findAll();
}

See also:

Custom implementations for Spring Data repositories

Configuring Fetch- and LoadGraphs

like image 193
JDon Avatar answered Dec 07 '25 04:12

JDon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!