I have Spring Boot project with 2 database configs.
Primary DB config:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(transactionManagerRef = "primaryTransactionManager", entityManagerFactoryRef = "primaryEntityManagerFactory", basePackages = { "com.example.repository.primary" })
public class PrimaryDbConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.primary.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.example.domain.primary").persistenceUnit("primary-persistence-unit").build();
}
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
And secondary:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager", basePackages = { "com.example.repository.secondary" })
public class SecondaryDbConfig {
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.secondary.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.example.domain.secondary").persistenceUnit("secondary-persistence-unit").build();
}
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
There is entity which is loaded with second DB:
@Entity
@Table(name = "users")
public class User {
@OneToMany(mappedBy = "user")
private List<Company> companies;
Using:
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
When I use UserRepository
, User
is retrieved but when I hit to load companies, I get com.sun.jdi.InvocationException occurred invoking method.
- com.sun.jdi.InvocationException occurred invoking method. If I change SecondaryDbConfig
to @Primary
or add fetch = FetchType.EAGER
then companies are retrieved as expected. I have tried adding @Transactional(transactionManager="secondaryTransactionManager")
but it didn't help.
What did I miss? What's the proper approach to lazy load entity properties when using not primary database config?
I have resolved this issue by adding @Transactional over @Service class.