【发布时间】:2015-07-31 06:39:44
【问题描述】:
我正在使用 spring-jpa。我有 2 个测试。
@Test
@Transactional
public void testFindAll() {
List<Engine> eList = engineService.findAll();
Engine e = eList.get(0); //this engine id=3
List<Translation> tList = e.getTranslations();
for(Translation t : tList) {
...
}
}
此方法因以下异常而失败:
org.hibernate.LazyInitializationException: 延迟初始化失败 角色集合:xxx.Engine.translations,无法初始化 代理 - 没有会话
但是,这种方法效果很好:
@Test
@Transactional
public void testFindOne() {
Engine e = engineService.findOne(3);
List<Translation> tList = e.getTranslations();
for(Translation t : tList) {
...
}
}
为什么翻译列表在一种情况下加载成功,而在另一种情况下却没有?
编辑:服务/回购代码:
public interface EngineRepository extends JpaRepository<Engine, Integer>
{
}
.
@Service
@Transactional
public class EngineService
{
@Autowired
private EngineRepository engineRepository;
public List<Engine> findAll()
{
return engineRepository.findAll();
}
public Engine findOne(Integer engId)
{
return engineRepository.findOne(engId);
}
}
.
public class Engine implements Serializable {
...
@OneToMany
@JoinColumn(name="ID", referencedColumnName="TRAN_ID", insertable=false, updatable=false, nullable=true)
@LazyCollection(LazyCollectionOption.EXTRA)
private List<Translation> translations;
...
}
配置:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"xxx.dao"})
@ComponentScan(basePackages = {"xxx.dao", "xxx.service", "xxx.bean"})
@PropertySource("classpath:application.properties")
public class SpringDataConfig {
@Autowired
private Environment environment;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(environment.getProperty("db.url"));
dataSource.setDriverClassName(environment.getProperty("db.driverClass"));
dataSource.setUsername(environment.getProperty("db.username"));
dataSource.setPassword(environment.getProperty("db.password"));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setDatabase(Database.POSTGRESQL);
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getProperty("hibernate.showSQL"));
properties.put("hibernate.format_sql", environment.getProperty("hibernate.formatSQL"));
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("xxx.model");
entityManagerFactoryBean.setJpaVendorAdapter(hibernateJpaVendorAdapter);
entityManagerFactoryBean.setJpaProperties(properties);
return entityManagerFactoryBean;
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
【问题讨论】:
-
能把
engineService.findAll()和engineService.findOne()的代码发一下吗? -
它只是包装了 engineRepository 方法
-
还要添加引擎实体的定义和jpa配置。
-
findAll() 正在返回一个分离实体的集合。然后当尝试遍历这些实体并访问惰性初始化集合时,
-
或者尝试使用@OnetoMany f etch=FetchType.Eggar
标签: java hibernate spring-data-jpa