Spring数据lazyload没有LazyInitializationException
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 被映射为 onetomany 并延迟加载。
在上面的代码中
classARepo.findOne(1);
正确执行。但是
List<ClassB> list = classA.getClassBs();
list.size();
因 LazyInitializationException 失败。
public interface ClassARepo extends CrudRepository<ClassA, Integer> {
}
TestA 的实例创建如下所示
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Transactional
@Component
public class TestClassJOB extends AbstractJob
{
@Autowired
TestClass indexer;
}
上下文:
<!-- 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" />
我尝试了很多资源都无法解决问题。显示以下错误消息 "could not initialize proxy - no Session".
问题的原因可能是什么?
当调用 classARepo.findOne(1) 时会话可用,为什么在延迟获取期间不可用 (list.size())?
问题是 TestClassJOB 的实例是由 Quartz 创建的。所以跨国代理没有应用到 class 这就是问题的原因。
我通过声明交易模板解决了这个问题
@Autowired
TransactionTemplate transactionTemplate;
然后将代码包装在
中
transactionTemplate.execute(new TransactionCallbackWithoutResult()
{
@Override
protected void doInTransactionWithoutResult(TransactionStatus status)
{
<code here>
}
}
@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 被映射为 onetomany 并延迟加载。
在上面的代码中
classARepo.findOne(1);
正确执行。但是
List<ClassB> list = classA.getClassBs();
list.size();
因 LazyInitializationException 失败。
public interface ClassARepo extends CrudRepository<ClassA, Integer> {
}
TestA 的实例创建如下所示
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Transactional
@Component
public class TestClassJOB extends AbstractJob
{
@Autowired
TestClass indexer;
}
上下文:
<!-- 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" />
我尝试了很多资源都无法解决问题。显示以下错误消息 "could not initialize proxy - no Session".
问题的原因可能是什么? 当调用 classARepo.findOne(1) 时会话可用,为什么在延迟获取期间不可用 (list.size())?
问题是 TestClassJOB 的实例是由 Quartz 创建的。所以跨国代理没有应用到 class 这就是问题的原因。
我通过声明交易模板解决了这个问题
@Autowired
TransactionTemplate transactionTemplate;
然后将代码包装在
中 transactionTemplate.execute(new TransactionCallbackWithoutResult()
{
@Override
protected void doInTransactionWithoutResult(TransactionStatus status)
{
<code here>
}
}