Search code examples
springspring-datalazy-loadingtransactional

Spring Data lazyload does not LazyInitializationException


@Component
@Transactional
public class TestClass extends AbstractClass
{
   @Autowire
   ClassARepo classARepo;

   @Override
   public void test() {
       ClassA classA = classARepo.findOne(1);
       List<ClassB> list = classA.getClassBs();
       list.size();
   }
}

ClassB is mapped as onetomany and lazily loaded.

In the above code

classARepo.findOne(1);

Executes correctly. but

List<ClassB> list = classA.getClassBs();
list.size();

Fails with LazyInitializationException.

public interface ClassARepo extends CrudRepository<ClassA, Integer> {
} 

Instance for TestA is created like the one below

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Transactional
@Component
public class TestClassJOB extends AbstractJob
{
    @Autowired
    TestClass indexer;
}

Context:

<!-- JPA mapping configuration -->
<bean id="persistenceXmlLocation" class="java.lang.String">
    <constructor-arg value="classpath:/persistence.xml"></constructor-arg>
</bean>

<!-- entity manager -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    p:dataSource-ref="dataSource" p:persistenceUnitName="jpaData"
    p:persistenceXmlLocation-ref="persistenceXmlLocation">
    <property name="packagesToScan" value="com..persist.entity" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
</bean>

<!-- transaction manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
    p:entityManagerFactory-ref="entityManagerFactory" lazy-init="true" p:dataSource-ref="dataSource" />

<!-- JPA repositories -->
<jpa:repositories base-package="com..persist.repo" 
    entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />

I tried many resources and could not solve the issue. The following error message is displayed "could not initialize proxy - no Session".

What could be the cause of the issue? When the session is available while classARepo.findOne(1) is called, why is not available during lazy fetch(list.size())?


Solution

  • The issue was the instance for TestClassJOB was created by Quartz. So the transnational proxy was not applied to the class which was the reason for the issue.

    I fixed the issue by declaring a transaction template

    @Autowired
    TransactionTemplate transactionTemplate;
    

    and then wrapping the code within

        transactionTemplate.execute(new TransactionCallbackWithoutResult()
        {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status)
            {
               <code here>
            }
       }