我正在使用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;
}
}
答案 0 :(得分:0)
我认为这里的问题是会话在第一种情况下的第一行之后关闭。您应该查看findAll()的JpaRepository实现。
答案 1 :(得分:0)
您的TestCase中似乎没有提供Spring Context,这意味着什么? @Transactional
被忽略了。因此,您最终会遇到关闭的会话异常,因为没有事务。
了解如何使用Spring Context here
配置TestCase@RunWith(SpringJUnit4ClassRunner.class)
// ApplicationContext will be loaded from AppConfig and TestConfig
@ContextConfiguration(classes = {AppConfig.class, TestConfig.class})
public class MyTest {
@Autowired
EngineService engineService;
@Test
@Transactional
public void testFindOne() {}
@Test
@Transactional
public void testFindAll() {}
}