I have a multiple datasource configuration and I'm trying to use the EntityManagerFactory of the secondary DB. Currently, when calling EntityManagerFactory, it only reference to primary DB configuration by retrieving error "Not an Entity". This is my configuration:
application.properties
spring.ds.datasource1.url=jdbc:postgresql:x
spring.ds.datasource1.username=user
spring.ds.datasource1.password=
spring.ds.datasource2.url=jdbc:postgresql:x
spring.ds.datasource2.username=user
spring.ds.datasource2.password=
Datasource 1 configuration:
@EnableJpaRepositories(basePackages = "eu.example", entityManagerFactoryRef = "ds1EntityManagerFactory", transactionManagerRef = "ds1TransactionManager")
@Configuration
public class Ds1DataSourceConfiguration {
private static final String DS1_ENTITY_MANAGER_FACTORY = "ds1EntityManagerFactory";
private static final String DS1_TRANSACTION_MANAGER = "ds1TransactionManager";
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.ds.datasource1")
public DataSourceProperties ds1DataSourceProperties() {
return new DataSourceProperties();
}
@Primary
@Bean
@ConfigurationProperties("spring.ds.datasource1")
public DataSource ds1DataSource(DataSourceProperties properties) {
return properties
.initializeDataSourceBuilder()
.build();
}
@Primary
@Bean(name = DS1_ENTITY_MANAGER_FACTORY)
public LocalContainerEntityManagerFactoryBean ds1EntityManagerFactoryBean(
EntityManagerFactoryBuilder factoryBuilder, DataSource ds1Ds) {
return factoryBuilder
.dataSource(ds1Ds)
.packages("eu.example.domain.entity.ds1")
.build();
}
@Primary
@Bean(name = DS1_TRANSACTION_MANAGER)
public PlatformTransactionManager ds1TransactionManager(
@Qualifier(DS1_ENTITY_MANAGER_FACTORY) LocalContainerEntityManagerFactoryBean managerFactoryBean) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(managerFactoryBean.getObject());
return jpaTransactionManager;
}
}
Datasource 2 configuration is similar to the configuration above without Primary annotation
Service class:
@Service
public class TestService{
private final EntityManagerFactory et2;
...
}
How can we reference et2 inside Service class to Datasource 2 EntityManagerFactory without using Persistence Unit?
Please refer EntityManager link
An EntityManager instance is associated with a persistence context. A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle are managed. The EntityManager API is used to create and remove persistent entity instances, to find entities by their primary key, and to query over entities.
Your configuration looks fine. refer this github repository link
We can define entity, repository and invoke inthe service layer.
Entity:
package eu.example.domain.entity.ds1.model;
@Entity
public class Customer implements Serializable {
// getter setters
}
Repository:
package eu.example.domain.entity.ds1.repository;
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {}
Service:
package eu.example.domain.entity.ds1.service;
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
CustomerRepository customerRepository;
@Override
public List<ClientSetting> findClientDataSourceSettings() {
return customerRepository.findAll();
}
}
Alternative
@Repository
public class CustomerInfoRepository {
@Autowired
@Qualifier("ds1EntityManagerFactoryBean")
private EntityManager entityManager;
public List<Customer> getCustomerInfo() {
Query query = entityManager.createNativeQuery(....);
return query.getResultList();
}
@Transactional("ds1TransactionManager")
public void updateCustomerInfo(String name, Long id) {
Query query = entityManager.createQuery(....);
query.executeUpdate();
}
}