Spring Boot多数据源LazyLoadingException

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

我有一个Spring启动应用程序(v1.4.3),我的对象使用默认的Jackson对象映射器进行序列化,如下所示:

@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