Spring Boot多数据源LazyLoadingException
我有一个Spring启动应用程序(v1.4.3),我的对象使用默认的Jackson对象映射器进行序列化,如下所示:Spring Boot多数据源LazyLoadingException,spring,hibernate,Spring,Hibernate,我有一个Spring启动应用程序(v1.4.3),我的对象使用默认的Jackson对象映射器进行序列化,如下所示: @RequestMapping(value = "diagnosis", method = RequestMethod.GET) public Object diagnosis(Filter filter, Pageable pageable) { if (filter) { return eventRepository.findAll(filter.to
@RequestMapping(value = "diagnosis", method = RequestMethod.GET)
public Object diagnosis(Filter filter, Pageable pageable) {
if (filter) {
return eventRepository.findAll(filter.toSpecification(), pageable)
}
return eventRepository.findAll(pageable)
}
如果我只定义一个数据源(application.yml'spring.datasource…',从spring自动配置),那么一切都正常
现在我需要配置两个数据源。对于每个数据源,我都编写了一个配置类
用户数据源
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xxx.repository.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager")
class DatasourceConfigurationUser {
@Autowired
private DatasourceSettingsUser datasourceSettingsUser
@Primary
@Bean(name = "userDataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource()
dataSource.setDriverClassName(datasourceSettingsUser.driverClassName)
dataSource.setUrl(datasourceSettingsUser.url)
dataSource.setUsername(datasourceSettingsUser.username)
dataSource.setPassword(datasourceSettingsUser.password)
return dataSource
}
/*
* Entity Manager Factory setup.
*/
@Primary
@Bean(name = "userEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean()
factoryBean.setDataSource(dataSource())
factoryBean.setPackagesToScan(["xxx.model.user"] as String[])
factoryBean.setJpaProperties(datasourceSettingsUser.toHibernateProperties())
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter())
return factoryBean
}
@Primary
@Bean(name = "userTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager()
txManager.setEntityManagerFactory(emf)
return txManager
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xxx.repository.data", entityManagerFactoryRef = "dataEntityManager", transactionManagerRef = "dataTransactionManager")
class DatasourceConfigurationData {
@Autowired
private DatasourceSettingsData datasourceSettingsData
@Bean(name = "dataDataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource()
dataSource.setDriverClassName(datasourceSettingsData.driverClassName)
dataSource.setUrl(datasourceSettingsData.url)
dataSource.setUsername(datasourceSettingsData.username)
dataSource.setPassword(datasourceSettingsData.password)
return dataSource
}
/*
* Entity Manager Factory setup.
*/
@Bean(name = "dataEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean()
factoryBean.setDataSource(dataSource())
factoryBean.setPackagesToScan(["xxx.model.data"] as String[])
factoryBean.setJpaProperties(datasourceSettingsData.toHibernateProperties())
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter())
return factoryBean
}
@Bean(name = "dataTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager()
txManager.setEntityManagerFactory(emf)
return txManager
}
}
数据源
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xxx.repository.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager")
class DatasourceConfigurationUser {
@Autowired
private DatasourceSettingsUser datasourceSettingsUser
@Primary
@Bean(name = "userDataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource()
dataSource.setDriverClassName(datasourceSettingsUser.driverClassName)
dataSource.setUrl(datasourceSettingsUser.url)
dataSource.setUsername(datasourceSettingsUser.username)
dataSource.setPassword(datasourceSettingsUser.password)
return dataSource
}
/*
* Entity Manager Factory setup.
*/
@Primary
@Bean(name = "userEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean()
factoryBean.setDataSource(dataSource())
factoryBean.setPackagesToScan(["xxx.model.user"] as String[])
factoryBean.setJpaProperties(datasourceSettingsUser.toHibernateProperties())
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter())
return factoryBean
}
@Primary
@Bean(name = "userTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager()
txManager.setEntityManagerFactory(emf)
return txManager
}
}
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xxx.repository.data", entityManagerFactoryRef = "dataEntityManager", transactionManagerRef = "dataTransactionManager")
class DatasourceConfigurationData {
@Autowired
private DatasourceSettingsData datasourceSettingsData
@Bean(name = "dataDataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource()
dataSource.setDriverClassName(datasourceSettingsData.driverClassName)
dataSource.setUrl(datasourceSettingsData.url)
dataSource.setUsername(datasourceSettingsData.username)
dataSource.setPassword(datasourceSettingsData.password)
return dataSource
}
/*
* Entity Manager Factory setup.
*/
@Bean(name = "dataEntityManager")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean()
factoryBean.setDataSource(dataSource())
factoryBean.setPackagesToScan(["xxx.model.data"] as String[])
factoryBean.setJpaProperties(datasourceSettingsData.toHibernateProperties())
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter())
return factoryBean
}
@Bean(name = "dataTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager()
txManager.setEntityManagerFactory(emf)
return txManager
}
}
现在我遇到了讨厌的LazyLoadingExceptions,因为在Jackson Mapper序列化期间无法获取惰性集合。我想知道为什么这与默认的Spring Boot数据源一起工作
在数据源配置过程中,我是否遗漏了什么
编辑1 这在服务层中工作
@Service
@Transactional
class EventService {
@Autowired
private EventRepository eventRepository
def findAll(Pageable pageable) {
Page<Event> page = eventRepository.findAll(pageable)
page.content.each {
it.config.event.size()
it.config.system.size()
it.config.subsystem.size()
}
return page
}
}
@服务
@交易的
类事件服务{
@自动连线
私有事件存储库事件存储库
def findAll(可分页可分页){
Page=eventRepository.findAll(可分页)
page.content.each{
it.config.event.size()
it.config.system.size()
it.config.subsystem.size()
}
返回页
}
}
但它对每个查询都非常具体:-(我认为最好引入服务层,而不是直接从控制器调用存储库。事务在服务层组织,服务返回DTO(而不是实体)。懒惰问题在服务层上得到解决,然后返回纯pojo DTO。在您的情况下,您可以发送关键信息,如实体层上定义的DB ID或密码。是的,您是对的。数据库密钥被@JsonIgnore跳过。但是如果创建服务,如何手动调用Jackson映射器来序列化结果?在我的示例中,这是s在外部自动完成。无需手动调用Jackson Mapper。服务使用某个EntityToDTOConverter返回DTO对象。然后您只需从控制器返回DTO。因此,服务方法被标记为事务性,并且在服务之后没有惰性/实体,只有纯pojo