There are two data source configuration classes:
#Configuration
#EnableJpaRepositories(
basePackages = {"com.proj.killbill.repository.kb", "com.proj.service.base.repository"},
entityManagerFactoryRef = "kbEntityManagerFactory",
transactionManagerRef = "kbTransactionManager")
#EnableJpaAuditing
#Profile({"dev", "prod"})
public class PersistenceKbConfig {
#Value("${db.user:default}")
private String user;
#Value("${db.password:default}")
private String password;
#Value("${db.url:default}")
private String jdbcUrl;
#Value("${app.kb.ds.jndi.name}")
private String kbDsJndiName;
#Bean(name = "kbDataSource")
#Profile("dev")
public DataSource devKbDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
#Bean(name = "kbDataSource")
#Profile("prod")
public DataSource prodKbDataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
return dsLookup.getDataSource(kbDsJndiName);
}
#SuppressWarnings("Duplicates")
#Bean(name = "kbEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
#Qualifier("kbDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.proj.service.base.domain");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
private Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
return properties;
}
#Bean(name = "kbTransactionManager")
public PlatformTransactionManager kbTransactionManager(
#Qualifier("kbEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
#Configuration
#EnableJpaRepositories(
basePackages = {"com.proj.killbill.repository.cm", "com.proj.service.base.repository"},
entityManagerFactoryRef = "cmEntityManagerFactory",
transactionManagerRef = "cmTransactionManager")
#EnableJpaAuditing
#Profile({"dev", "prod"})
public class PersistenceCmConfig {
#Value("${cm.db.user:default}")
private String user;
#Value("${cm.db.password:default}")
private String password;
#Value("${cm.db.url:default}")
private String jdbcUrl;
#Value("${app.cm.ds.jdni.name}")
private String cmJndiName;
private static final Logger LOGGER = LogManager.getLogger(PersistenceCmConfig.class);
#Bean(name = "cmDataSource")
#Profile("dev")
public DataSource devCmDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(user);
dataSource.setPassword(password);
LOGGER.debug("CM JDBC URL USER/PASSWORD" + jdbcUrl + " " + user + "/" + password);
return dataSource;
}
#Bean(name = "cmDataSource")
#Profile("prod")
public DataSource prodCmDataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
return dsLookup.getDataSource(cmJndiName);
}
#SuppressWarnings("Duplicates")
#Bean(name = "cmEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean cmEntityManagerFactory(
#Qualifier("cmDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.proj.service.base.domain");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
private Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
return properties;
}
#Bean(name = "cmTransactionManager")
public PlatformTransactionManager cmTransactionManager(
#Qualifier("cmEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
Entity managers use #Qualifier annotations to inject appropriate data sources. But when I start the app I get the exception:
==========
Parameter 0 of method cmEntityManagerFactory in com.proj.killbill.config.PersistenceCmConfig required a single bean, but 2 were found:
- cmDataSource: defined by method 'devCmDataSource' in class path resource [com/proj/killbill/config/PersistenceCmConfig.class]
- kbDataSource: defined by method 'devKbDataSource' in class path resource [com/proj/killbill/config/PersistenceKbConfig.class]
Action:
Consider marking one of the beans as #Primary, updating the consumer to accept multiple beans, or using #Qualifier to identify the bean that should be consumed
============
#Qualifier("cmDataSource") is just ignored for unknown reason. Why can it be possible?
Related
I have a little program with Java Netbeans and the Spring framework, but I have the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'config': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.driverClassName' in value "${spring.datasource.driverClassName}"
I have Config.Java using the following code:
#Configuration
#EnableTransactionManagement
#EnableAutoConfiguration(exclude = { HibernateJpaAutoConfiguration.class})
#ComponentScans(value = { #ComponentScan("boot.entry"),
#ComponentScan("Model"),
#ComponentScan("Controller"),
#ComponentScan("DAO"),
#ComponentScan("Miscallaneous"),
#ComponentScan("Service")})
public class Config {
#Value("${spring.datasource.driverClassName}")
private String DB_DRIVER;
#Value("${db.password}")
private String DB_PASSWORD;
#Value("${db.url}")
private String DB_URL;
#Value("${db.username}")
private String DB_USERNAME;
#Value("${hibernate.dialect}")
private String HIBERNATE_DIALECT;
#Value("${hibernate.show_sql}")
private String HIBERNATE_SHOW_SQL;
#Value("${hibernate.hbm2ddl.auto}")
private String HIBERNATE_HBM2DDL_AUTO;
#Value("${entitymanager.packagesToScan}")
private String ENTITYMANAGER_PACKAGES_TO_SCAN;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
sessionFactory.setHibernateProperties(hibernateProperties);
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory().getObject());
return txManager;
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver resolver= new InternalResourceViewResolver();
resolver.setPrefix("/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
And my apliccation.properties with this code (it is for SQL Server):
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=Prueba
spring.datasource.username=UserLogin
spring.datasource.password=Miguel123
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql = true
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
I am trying to connect to SQL Server using a web service with Angular.
I'm trying to configure Spring Boot to use 2 datasources using JNDI:
application.properties:
spring.production.datasource.jndi-name=java:/global/production_gateway
spring.production.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.production.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.production.datasource.jpa.show-sql = true
spring.production.datasource.jpa.hibernate.ddl-auto = update
spring.warehouse.datasource.jndi-name=java:/global/production_warehouse
spring.warehouse.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.warehouse.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.warehouse.datasource.jpa.show-sql = true
spring.warehouse.datasource.jpa.hibernate.ddl-auto = update
Primary datasource:
#Configuration
#EnableJpaRepositories(
basePackages = "org.datalis.plugin.production.entity",
entityManagerFactoryRef = "productionEntityManager",
transactionManagerRef = "productionTransactionManager"
)
#EnableTransactionManagement
public class ContextProductionDatasource {
#Primary
#Bean(name = "productionDataSourceProperties")
#ConfigurationProperties(prefix="spring.production.datasource")
public JndiPropertyHolder productionDataSourceProperties() {
return new JndiPropertyHolder();
}
#Primary
#Bean(name = "productionDataSource")
#ConfigurationProperties(prefix="spring.production.datasource")
public DataSource productionDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(productionDataSourceProperties().getJndiName());
return dataSource;
}
#Primary
#Bean(name = "productionEntityManager")
public EntityManager productionEntityManager(EntityManagerFactory emf) {
return emf.createEntityManager();
}
#Primary
#PersistenceContext(unitName = "production")
#Bean(name = "productionLocalEntityManager")
public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder.dataSource(productionDataSource()).persistenceUnit("production").packages("org.datalis.plugin.production.entity").build();
}
#Primary
#Bean(name = "productionTransactionManager")
public PlatformTransactionManager productionTransactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Primary
#Bean(name = "productionExceptionTranslation")
public PersistenceExceptionTranslationPostProcessor productionExceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private static class JndiPropertyHolder {
private String jndiName;
public String getJndiName() {
return jndiName;
}
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
}
}
I try to use the entity manager this way:
#Service
#Transactional(value = "productionEntityManager")
public class ..... {
#PersistenceContext(unitName = "production")
private EntityManager entityManager;
}
But I get an error during deployment:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
Do you know where my configuration is wrong?
You seem to be missing a bean for EntityManagerFactory. You're requesting it here:
public EntityManager productionEntityManager(EntityManagerFactory emf) {
Try adding
#Primary
#Bean(name = "productionEntityManagerFactory")
public EntityManagerFactory productionEntityManagerFactory() {
return Persistence.createEntityManagerFactory("production");
}
I have 2 instances of DB. Each for a different client. This is my hibernate config class :
public class HibernateConfiguration {
#Autowired
private Environment environment;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[]{"com.mhycomoant.test.model"});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.id.new_generator_mappings","false");
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(s);
return transactionManager;
}
}
Here is my Dao class
#Repository
#Transactional()
#EnableTransactionManagement
public class PersonDaoImpl implements PersonDao {
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
#Override
public Serializable save(Person wt) {
return getCurrentSession().save(wt);
}
#Override
public List<Person> list() {
throw new UnsupportedOperationException("Not supported yet.");
//Session session = this.sessionFactory.openSession();
// List<WalletTransaction> personList = session.createQuery("from person").list();
// session.close();
// return personList;
}
How can I switch the DB's at the runtime?
I have the following configuration:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackageClasses = DemoApplication.class)
public class JpaConfig implements TransactionManagementConfigurer {
#Value("${dataSource.driverClassName}")
private String driver;
#Value("${dataSource.url}")
private String url;
#Value("${dataSource.username}")
private String username;
#Value("${dataSource.password}")
private String password;
#Value("${hibernate.dialect}")
private String dialect;
#Value("${hibernate.hbm2ddl.auto}")
private String hbm2ddlAuto;
#Bean
public DataSource configureDataSource() {
HikariConfig config = new HikariConfig();
config.setDriverClassName(driver);
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
return new HikariDataSource(config);
}
#Bean
public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(configureDataSource());
entityManagerFactoryBean.setPackagesToScan("com.dataart.cashmashine");
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = new Properties();
jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
entityManagerFactoryBean.setJpaProperties(jpaProperties);
return entityManagerFactoryBean;
}
#Bean
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new JpaTransactionManager();
}
#Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
return hemf.getSessionFactory();
}
}
application.properties:
dataSource.driverClassName=org.postgresql.Driver
dataSource.url=jdbc:postgresql://localhost:5432/cash_mashine
dataSource.username=marc
dataSource.password=marc
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.hbm2ddl.auto=create-drop
In dao I write following rows:
#Autowired
private SessionFactory sessionFactory;
#Override
public CreditCard findCard(String cardNumber) {
Session currentSession = sessionFactory.getCurrentSession();
when executes
sessionFactory.getCurrentSession()
I see following error:
Caused by: org.hibernate.HibernateException: No CurrentSessionContext
configured!
How to fix this?
spring:
jpa:
properties:
hibernate:
current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext
above config in application.yml can solve this problem.
Try adding #Transactional at a public service method which is invoking the DAO.
here are my 3 classes:
#Configuration //Marks this class as configuration
//Specifies which package to scan
#ComponentScan({"pl.jpet"})//,"pl.dup"})
//Enables Spring's annotations
#EnableWebMvc
//#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class Config {
#Resource
private Environment env;
#Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/wikidb");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
#Bean
#Autowired
public EntityManagerFactory entityManagerFactory(BasicDataSource dataSource) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
vendorAdapter.setDatabase(Database.MYSQL);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setDataSource(dataSource);
factory.setPersistenceUnitName("wikidb");
factory.setPackagesToScan("pl.jpet");
factory.afterPropertiesSet();
return factory.getObject();
}
#Bean
#Autowired
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
JpaDialect jpaDialect = new HibernateJpaDialect();
txManager.setEntityManagerFactory(entityManagerFactory);
txManager.setJpaDialect(jpaDialect);
return txManager;
}
----------------------------------------------------------------------
package pl.jpet.model;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Data
#Table(name="zrobmitabele")
public class TestModel {
#Id
#Column(name = "name", nullable = false)
private String name;
}
-----------------------------------------------------------------------------
#Transactional
#RestController
#RequestMapping("/una")
public class UnauthenticatedController {
#PersistenceContext
private EntityManager em;
#Transactional
#RequestMapping(method = RequestMethod.GET,value="/checkLogin")
public ResponseEntity<String> checkLogin() throws IOException {
TestModel test = new TestModel();
test.setName("KUBA");
em.persist(test);
return new ResponseEntity<String>(HttpStatus.OK);
}
}
I'm getting this info on start "INFO [org.hibernate.cfg.Environment] (MSC service thread 1-1) HHH000206: hibernate.properties not found" but still it's not crushing, even after I'm making call to "/una" service it's not throwing anything - Guess there's something wrong with my Config class but i have no idea what, anyone ?
I missed #EnableTransactionManagement on my config class
#_#