Connection with multiple database with spring boot - java

Showing error while connecting to database using spring boot:
classMethod FAILED
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/tomtom/workflow/iris/uitest/DatabaseConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by:
javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by:
org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
Caused by:
org.postgresql.util.PSQLException: The connection attempt failed.
Caused by:
java.net.SocketTimeoutException: connect timed out
Properties:
# PostgreSQL DB - "iris"
spring.datasource.jdbc-url= jdbc:postgresql://172.xx.xx.93:5442/workflow?currentSchema=workflow
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.username=workflow
spring.datasource.password=workflow
# PostgreSQL DB - "accesspoint"
secondary.datasource.jdbc-url=jdbc:postgresql://172.xx.xxx.44:5442/workflow?currentSchema=accesspoint
secondary.datasource.username=dba_admin
secondary.datasource.password=dba_admin
hibernate.dialect=org.hibernate.dialect.PostgreSQL82Dialect
hibernate.hbm2ddl.auto= update
Classes For bean.For secondary datasource:
package com.tomtom.workflow.acesspoint;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "accessPointEntityManagerFactory",
transactionManagerRef = "accessPointTransactionManager",
basePackages = { "com.tomtom.workflow.acesspoint" }
)
public class AccessPointDbConfiguration {
#Autowired
private Environment env;
#Bean(name = "accessPointDataSource")
#ConfigurationProperties(prefix = "accesspoint.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Bean(name = "accessPointEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean accessPointEntityManagerFactory() {
/*
* return builder .dataSource(dataSource)
* .packages("com.tomtom.workflow.acesspoint") .persistenceUnit("baseline_info")
* .build();
*/
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.tomtom.workflow.acesspoint" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean(name = "accessPointTransactionManager")
public PlatformTransactionManager accessPointTransactionManager(
#Qualifier("accessPointEntityManagerFactory") EntityManagerFactory accessPointEntityManagerFactory) {
return new JpaTransactionManager(accessPointEntityManagerFactory);
}
}
For Primary datasource i have written this class.
package com.tomtom.workflow.iris.uitest;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", basePackages = {
"com.tomtom.workflow.iris.uitest" })
#Profile(Profiles.DATABASE)
class DatabaseConfiguration {
#Autowired
private Environment env;
#Primary
#Bean(name = "dataSource")
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Primary
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.tomtom.workflow.iris.uitest.db.model" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
#Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
I have connected both the database by pg admin and they are active.
Please help.

Related

Spring batch issue in using multiple datasource facing IllegalStateException: Could not open JPA EntityManager for transaction: Already value

I am trying to use multiple datasource in spring batch where first step connects to one database (sybase) and second step connects to differnt datasoruce (posgres) but I am getting below error when ever I try to run the same :
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#713a4f8d] for key [org.springframework.jdbc.datasource.DriverManagerDataSource#25a51f53] bound to thread [http-nio-9093-exec-1]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:448)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400)
..
..
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#713a4f8d] for key [org.springframework.jdbc.datasource.DriverManagerDataSource#25a51f53] bound to thread [http-nio-9093-exec-1]
at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:193)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:423)
#Configuration
#EnableJpaRepositories(
basePackages = "com.**.dao.posgres",
entityManagerFactoryRef = "positionEntityManager",
transactionManagerRef = "positionTransactionManager"
)
#EnableTransactionManagement
#EnableAutoConfiguration
public class PosgresdbConfig {
#Autowired
private Environment env;
#Bean
#Primary
#Qualifier("positionEntityManager")
public LocalContainerEntityManagerFactoryBean positionEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(positionDataSource());
em.setPackagesToScan(
new String[] { "com.**.dao.posgres" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
#Primary
#Qualifier("positionDataSource")
public DataSource positionDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("datasource.posgres.driver-class-name"));
dataSource.setUrl(env.getProperty("datasource.posgres.url"));
dataSource.setUsername(env.getProperty("datasource.posgres.username"));
dataSource.setPassword(env.getProperty("datasource.posgres.password"));
return dataSource;
}
#Bean
#Primary
#Qualifier("positionTransactionManager")
public PlatformTransactionManager positionTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
positionEntityManager().getObject());
return transactionManager;
}
}
#Configuration
#EnableJpaRepositories(
basePackages = "com.**.dao.Sybase",
entityManagerFactoryRef = "SybaseEntityManager",
transactionManagerRef = "SybaseTransactionManager"
)
public class SybasedbConfig {
#Autowired
private Environment env;
#Bean
public LocalContainerEntityManagerFactoryBean SybaseEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(sybaseDataSource());
em.setPackagesToScan(
new String[] { "com.**.Sybase" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public DataSource sybaseDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("datasource.posgres.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
#Bean
public PlatformTransactionManager SybaseTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
SybaseEntityManager().getObject());
return transactionManager;
}
}
BATCH CONFIG
#Bean
public Step loadPositionData(final ItemReader<PositionDataResult> positionDataReader,
final ItemProcessor<Object, PositionDataResult> positionRecordProcessor,
final ItemWriter<Object> positionFileWriter) {
return stepBuilderFactory.get("position-load-account")
.<LoadPositionForRiskSP, LoadPositionForRiskSP>chunk(2000)
.reader(positionDataReader)
.processor(positionRecordProcessor)
.writer(positionFileWriter)
.listener(new NoDataFoundListener())
.transactionManager(positionTransactionManager)
.build();
}
Using first datasource works fine in first step reader:
#Transactional(value="SybaseTransactionManager", propagation= Propagation.NOT_SUPPORTED, isolation= Isolation.READ_UNCOMMITTED,readOnly = true)
public PositionDataResult loadDataFromSP() {}
Now using secondary datasource in second step gives error:
#Transactional(transactionManager="positionTransactionManager", readOnly = true, propagation = Propagation.REQUIRED, noRollbackFor = Exception.class)
public void write(List<? extends Object> list) throws Exception {}
The issue is related to making the ItemWriter#write method transactional here:
#Transactional(transactionManager="positionTransactionManager", readOnly = true, propagation = Propagation.REQUIRED, noRollbackFor = Exception.class)
public void write(List<? extends Object> list) throws Exception {}
The item writer will be called in a transaction driven by Spring Batch, so this annotation is not needed and should be removed. Same thing for the reader as well. The transaction manager and the transaction attributes of the step should defined using the methods on the StepBuilder.
If the step involves multiple transactional resources, then a JtaTransactionManager should be used to coordinate the transactions between those resources.

Spring boot Hibernate data source exception null exception on application start up

Getting
ERROR [SpringApplication] Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEntityManagerFactory' defined in class path resource [com/employees/service/config/DBConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean
Caused by: java.lang.NullPointerException at
org.hibernate.boot.model.source.internal.hbm.ModelBinder$AbstractPluralAttributeSecondPass.bindCollectionElement(ModelBinder.java:3554)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.hibernate.boot.model.source.internal.hbm.ModelBinder$AbstractPluralAttributeSecondPass.doSecondPass(ModelBinder.java:3133)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1696)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1664)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:287)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935)
~[hibernate-core-5.3.7.Final.jar:5.3.7.Final] at
org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
for code
#ConfigurationProperties(prefix = "spring.datasource.employees")
#Bean
public DataSource myDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
public LocalContainerEntityManagerFactoryBean myEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean employees = createEntityManagerFactory(
myDataSource(), "Employees",
MyMapping.MAPPINGS);
return employees;
}
#Bean
public EntityManager myEntityManager(#Qualifier("myEntityManagerFactory")
EntityManagerFactory emf) {
return entityManager(emf);
}
#Bean
public JpaTransactionManager myTransactionManager(#Qualifier("myEntityManagerFactory")
EntityManagerFactory emf) {
return transactionManager(emf);
}
#Bean
public TransactionHelper myTransactionHelper(
#Qualifier("myTransactionManager")
JpaTransactionManager transactionManager) {
TransactionHelper transactionHelper = new TransactionHelper();
transactionHelper.setPlatformTransactionManager(transactionManager);
return transactionHelper;
}
// Common methods
private LocalContainerEntityManagerFactoryBean createEntityManagerFactory(
DataSource dataSource, String persistenceUnitName, String[] mappings) {
MyLocalContainerEntityManagerFactoryBean entityManagerFactory
= new MyLocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setPersistenceUnitName(persistenceUnitName);
entityManagerFactory.setPackagesToScan("com.employees.domain");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactory.setJpaVendorAdapter(vendorAdapter);
entityManagerFactory.setJpaProperties(additionalProperties());
if (mappings != null) {
entityManagerFactory.setMappingResources(mappings);
}
return entityManagerFactory;
}
private JpaTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
private EntityManager entityManager(EntityManagerFactory emf) {
return SharedEntityManagerCreator.createSharedEntityManager(emf);
}
#Bean
#Primary
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "none");
// properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.implicit_naming_strategy",
"com.employees.domain.hibernate.BackwardsCompatibleImplicitNamingStrategy");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
return properties;
}
#Bean public TraceProperties traceProperties() {
TraceProperties traceProperties = new TraceProperties();
Set<TraceProperties.Include> includes = new HashSet<>();
includes.addAll(Arrays.asList(TraceProperties.Include.values()));
traceProperties.setInclude(includes);
return traceProperties;
}
In my case, this issue was related to hibernate mappings. There was one .hbm file that had a nested table in it or an association that was not defined when creating database connection entity manager factory.

org.hibernate.LazyInitializationException in spring data jpa

I met 'org.hibernate.LazyInitializationException: could not initialize proxy - no Session' in spring data jpa.
Below is my code.
// this is service layer
#Transactional(rollbackFor = Exception.class)
public BlogEntity saveBlog(BlogEntity blogEntityInput) {
BlogEntity blogEntity = blogDao.find(blogEntityInput.getId());
System.out.println(blogEntity);
return blogDao.saveBlog(blogEntityInput);
}
// this is dao layer which will call
#Override
public BlogEntity find(Integer id) {
return blogRepository.getOne(id); // JpaRepository#getOne
}
The exception will occur when I print the blogEntity after I call getOne. I know that getOne is lazy loaded.
But I have already add the #Transactional which will ensure the inner method will be in a hibernate session. How could the LazyInitializationException still occur?
Thanks.
Below is my full database related spring code.
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "h2_entityManagerFactory",
basePackages = { "com.taobao.rest.repository.h2" },
transactionManagerRef = "h2_manager"
)
public class H2DBConfig {
#Primary
#Bean(name = "h2_dataSource")
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:~/new-taobao");
dataSource.setUsername("taobao");
dataSource.setPassword("");
return dataSource;
}
#Primary
#Bean(name = "h2_entityManagerFactory")
public LocalContainerEntityManagerFactoryBean h2EntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.taobao.rest.entity.h2" });
em.setPersistenceUnitName("h2_unit");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty(
"hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.setProperty("hibernate.show_sql", "true");
return properties;
}
#Bean(name = "h2_manager")
public PlatformTransactionManager transactionManager(
#Qualifier("h2_entityManagerFactory") EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}

Spring 4 + Spring repositories + hibernate 5: Error create java config

I have spring 4 app and I want use spring repositories. I tried include spring jpa_hibernate
compile 'org.springframework.data:spring-data-jpa:1.11.4.RELEASE'
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.0.5.Final'
and create config like oficial spring doc:
#Configuration
#ComponentScan("my.domain")
#EnableJpaRepositories("my.domain")
#EnableTransactionManagement
public class ApplicationConfiguration {
#Bean
public Config getConfig() {
return ConfigLoader.load();
}
#Bean
#Autowired
public DataSource getDatasource(Config config) throws Exception {
Properties props = new Properties();
Config dbConfig = config.getConfig("db.config");
dbConfig.entrySet().forEach(entry -> props.put(entry.getKey(), entry.getValue().unwrapped()));
return new DataSourceFactory().createDataSource(props);
}
#Bean
#Autowired
public NamedParameterJdbcTemplate getJdbcTemplate(DataSource datasource) {
return new NamedParameterJdbcTemplate(datasource);
}
#Bean
#Autowired
public PlatformTransactionManager getTransactionManager(DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
#Bean
#Autowired
public EntityManagerFactory entityManagerFactory(DataSource datasource) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setDataSource(datasource);
factory.afterPropertiesSet();
return factory.getObject();
}
#Bean
#Autowired
public PlatformTransactionManager transactionManager(DataSource datasource) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory(datasource));
return txManager;
}
}
But I get error when tried run app:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in my.ApplicationConfiguration:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate
[javax.persistence.EntityManagerFactory]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.IllegalStateException:
Failed to determine Hibernate PersistenceProvider
I used repositories in springboot and Configure in file, But I not found worck actual example for java config spring(not boot only simple core app)
As you are using latest Spring Data release, upgrade to the latest Hibernate release:
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.10.Final'
Spring requires hibernate's EntityManagerFactory implementation which previosly was provisioned by separate jar which is now deprecated, so you need only single hibernate-core dependency.
Also consider using following configuration:
#Configuration
#ComponentScan("my.domain")
#EnableJpaRepositories("my.domain")
#EnableTransactionManagement
public class ApplicationConfiguration {
#Bean
public Config getConfig() {
return ConfigLoader.load();
}
#Bean
public DataSource getDatasource(Config config) throws Exception {
Properties props = new Properties();
Config dbConfig = config.getConfig("db.config");
dbConfig.entrySet().forEach(entry -> props.put(entry.getKey(), entry.getValue().unwrapped()));
return new DataSourceFactory().createDataSource(props);
}
#Bean
public NamedParameterJdbcTemplate getJdbcTemplate(DataSource datasource) {
return new NamedParameterJdbcTemplate(datasource);
}
#Bean
#Autowired
public PlatformTransactionManager getTransactionManager(DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setDataSource(dataSource());
factory.setPackagesToScan("my.domain");
return factory;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
You were referencsing old spring data documentation, current version is available here.

DataSourceInitializer does not get called

I am setting up java config for database in my spring mvc app, and what I cannot figure out is why DataSourceInitializer bean does not get created, i.e. dataSourceInitializer method is never called.
#Configuration
#EnableJpaRepositories(basePackageClasses = {CustomerRepository.class})
#EnableTransactionManagement
public class DatabaseConfig {
#Resource
Environment environment;
#Bean
public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
return new NamedParameterJdbcTemplate(dataSource);
}
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.user"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.pwd"));
return dataSource;
}
#Bean
public DataSourceInitializer dataSourceInitializer(DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
#Bean
public DatabasePopulator databasePopulator() {
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
databasePopulator.addScript(new ClassPathResource("classpath:/db/sql/create-db.sql", DatabaseConfig.class));
databasePopulator.addScript(new ClassPathResource("classpath:/db/sql/insert-data.sql", DatabaseConfig.class));
return databasePopulator;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) throws Exception {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setPersistenceUnitName("CustomersPU");
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.myapp.domain");
factory.setDataSource(dataSource);
factory.setJpaProperties(jpaProperties());
return factory;
}
Properties jpaProperties() {
Properties props = new Properties();
props.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
props.put("hibernate.hbm2ddl.auto", "validate");
...
return props;
}
}
UPDATE: Exception that I get is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/myapp/conf/DatabaseConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: CustomersPU] Unable to build Hibernate SessionFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at ....
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: CustomersPU] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:877)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:805)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at ...
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [CUSTOMERS]
at org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateTable(SchemaValidatorImpl.java:67)
at org.hibernate.tool.schema.internal.SchemaValidatorImpl.doValidation(SchemaValidatorImpl.java:50)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:91)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:484)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:802)
... 62 more
What I am looking for is to have it configured similar to this configuration: embedded database + special username and password + paths to schema and insertion sql files. Like described here https://github.com/JohnathanMarkSmith/HelloSpringJavaBasedJavaConfig
UPDATE
If I just use EmbeddableDatabase, then it does not allow me to define username, password and DB connection URL, which is necessary to me. The following example works, but it does not allow me to define username, password and DB connection URL.
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:/db/sql/create-db.sql")
.addScript("classpath:/db/sql/insert-data.sql")
.build();
}

Categories