C3P0 exhausted after call some #Transactional methods - multi-tenant

I've implemented a multi tenant architecture and I've introduced a C3P0 connection pool.
By GUI I try to query my application with a simple search form. THis form has a button to call a back end method to extract my result.
If I click several times my search I've my application freeze because C3P0 connection pool is exhausted.
Because C3P0 increment connections managed with acquireIncrement parameter but when it arrived MAX_SIZE crashes
So my scenario is the follow:
I've a class annoted as #Service and a method annoted as #Transactional where I'm executing my query, as follow:
#Override
#Transactional
public String findPatientCountDao(Paziente paziente,
boolean searchForAllPatients, boolean enabledDemetra) {
String querySqlOrHql = this.createQuery(paziente, searchForAllPatients, true, 0, 0);
Query q = getSession().createQuery(querySqlOrHql);
List<Object[]> obj = q.list();
return "" + obj.get(0);
}
My Hibernate configuration has managed by HibernateConf class, as follow:
#Configuration
#EnableTransactionManagement
public class HibernateConf {
#Autowired
DataSourceBasedMultiTenantConnectionProviderImpl dataSources;
#Autowired
TenantSchemaResolver tenantSchemaResolver;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
if (TenantContext.getCurrentTenant()==null)
TenantContext.setCurrentTenant("tenant_1");
sessionFactory.setDataSource(dataSources.selectDataSource(TenantContext.getCurrentTenant()));
sessionFactory.setPackagesToScan("it.spi");
org.hibernate.cfg.Configuration configuration = new org.hibernate.cfg.Configuration();
configuration.setProperties(hibernateProperties());
//sessionFactory.setHibernateProperties(hibernateProperties());
sessionFactory.setConfigLocation(new ClassPathResource("hibernate_ehr/hibernate.cfg.xml"));
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Java Config serviceRegistry created");
sessionFactory = (LocalSessionFactoryBean) configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager =
new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
private final Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
hibernateProperties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, dataSources);
hibernateProperties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantSchemaResolver);
hibernateProperties.put(Environment.USE_STREAMS_FOR_BINARY, true);
hibernateProperties.put(Environment.DIALECT, "org.hibernate.dialect.Oracle10gDialect");
hibernateProperties.put(Environment.DRIVER, "oracle.jdbc.OracleDriver");
hibernateProperties.put(Environment.SHOW_SQL, false);
hibernateProperties.put(Environment.FORMAT_SQL, false);
hibernateProperties.put(Environment.USE_SQL_COMMENTS, false);
hibernateProperties.put(Environment.C3P0_MIN_SIZE, 50); //Minimum size of pool
hibernateProperties.put(Environment.C3P0_MAX_SIZE, 100); //Maximum size of pool
hibernateProperties.put(Environment.C3P0_ACQUIRE_INCREMENT, 10);//Number of connections acquired at a time when pool is exhausted
hibernateProperties.put(Environment.C3P0_TIMEOUT, 1800); //Connection idle time
hibernateProperties.put(Environment.C3P0_MAX_STATEMENTS, 600); //PreparedStatement cache size
return hibernateProperties;
}
My Datasource configuration:
#Primary
#Bean(name = { "dataSource", "dataSource1" })
#ConfigurationProperties(prefix = "spring.multitenancy.datasource1")
public DataSource dataSource1() {
DataSourceBuilder factory = DataSourceBuilder
.create(this.multitenancyProperties.getDatasource1().getClassLoader())
.driverClassName(this.multitenancyProperties.getDatasource1().getDriverClassName())
.username(this.multitenancyProperties.getDatasource1().getUsername())
.password(this.multitenancyProperties.getDatasource1().getPassword())
.url(this.multitenancyProperties.getDatasource1().getUrl()).type(ComboPooledDataSource.class);
return factory.build();
}
My database.properties file
spring.multitenancy.datasource.type = com.mchange.v2.c3p0.ComboPooledDataSource
spring.multitenancy.datasource.url=jdbc:oracle:thin:#xx.xx.xx.xx:1521/xxx
spring.multitenancy.datasource.username=xxx
spring.multitenancy.datasource.password=yyy
spring.multitenancy.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.multitenancy.datasource.testWhileIdle = true
spring.multitenancy.datasource.validationQuery = SELECT 1
spring.multitenancy.datasource.hibernate.c3p0.max_size=100
spring.multitenancy.datasource.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory

Related

How to set initial connections of a dynamic data source

I have a multi-tenant application with multiple datasources. The exact url which its connecting is set by runtime, depending on a request parameter. When I make a request at default 10 database-connections are created. With multiple datasources this fast sums up to a lot of connections. So I want to lower that number and also close the connections after a certain time.
My Configuration Class:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = "com.example.demo",
entityManagerFactoryRef = "multiEntityManager",
transactionManagerRef = "multiTransactionManager"
)
public class PersistenceConfiguration extends WebMvcConfigurerAdapter {
private final String PACKAGE_SCAN = "com.example.demo";
//datasources
#Primary
#Bean(name = "COMP1")
public DataSource company1DS() {
return DataSourceBuilder.create()
.username("root")
.password("password")
.url("jdbc:mysql://81.123.456.789:3306/company1")
.build();
}
#Bean(name = "COMP2")
public DataSource company2DS() {
return DataSourceBuilder.create()
.username("root")
.password("password")
.url("jdbc:mysql://81.123.456.789:3306/company2")
.build();
}
#Bean(name = "multiRoutingDataSource")
public DataSource multiRoutingDataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("COMP1", company1DS());
targetDataSources.put("COMP2", company2DS());
MultiRoutingDataSource multiRoutingDataSource = new MultiRoutingDataSource();
multiRoutingDataSource.setDefaultTargetDataSource(company1DS());
multiRoutingDataSource.setTargetDataSources(targetDataSources);
return multiRoutingDataSource;
}
#Bean(name = "multiEntityManager")
public LocalContainerEntityManagerFactoryBean multiEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(multiRoutingDataSource());
em.setPackagesToScan(PACKAGE_SCAN);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(hibernateProperties());
return em;
}
#Bean(name = "multiTransactionManager")
public PlatformTransactionManager multiTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
multiEntityManager().getObject());
return transactionManager;
}
#Primary
#Bean(name = "dbSessionFactory")
public LocalSessionFactoryBean dbSessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(multiRoutingDataSource());
sessionFactoryBean.setPackagesToScan(PACKAGE_SCAN);
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
return properties;
}
}
What I already tried:
I tried to change the values in the application.properties file like so:
spring.datasource.maxActive=2
spring.datasource.minIdle=2
spring.datasource.maxIdle=5
spring.datasource.initialSize=2
I tried to change the properties the dynamic way (PersistenceConfiguration.hibernateProperties()):
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("spring.datasource.maxActive",2);
properties.put("spring.datasource.minIdle",2);
properties.put("spring.datasource.maxIdle",5);
properties.put("spring.datasource.initialSize",2);
return properties;
}
But it seems that no properties get applied. When I show SHOW GLOBAL STATUS LIKE 'Connections'; in the MySQL workbench, I always get 10 more connections after I made a request from a new datasource.
If there is any important information missing, please let me know and I will add it.
I really appreciate your effort,
Greetings Alexander
EDIT
Since spring.datasource.max-active=2 is not valid, I also tried all the following in application-properties, as well as in the hibernateProperties();
spring.datasource.hikari.maximum-pool-size=2
spring.datasource.tomcat.initial-size=2
spring.datasource.tomcat.max-idle=2
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
properties.put("spring.datasource.hikari.maximum-pool-size",2);
properties.put("spring.datasource.tomcat.initial-size",2);
properties.put("spring.datasource.tomcat.max-idle",2);
properties.setProperty("spring.datasource.hikari.maximum-pool-size","2");
properties.setProperty("spring.datasource.tomcat.initial-size","2");
properties.setProperty("spring.datasource.tomcat.max-idle","2");
return properties;
}
Nothing changed a thing

Wrong transaction manger is being used in Spring

I have two spring transaction managers.
txManager1 - ChainedKafkaTransactionManager (KafkaTransactionManager,JpaTransactionManager) configured with datasource DB1
txManager2 - JpaTransactionManager configured with datasource DB2
The problem is that I perform some operation using txManager2 but somehow txManager1 is being used instead of txManager2 and the data is getting committed to DB1 instead of DB2.
#Autowired
#Qualifier("common-tx")
private PlatformTransactionManager txManager2 ;
#KafkaListener(topics = "${kafka.topic.name}", groupId = "group-1", containerFactory = "customKafkaListenerContainerFactory")
public void topicListener(String message, Acknowledgment ack)
throws InterruptedException, ClassNotFoundException, IOException {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName(domainEvent.getEventId());
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus commonStatus = txManager2 .getTransaction(def);
someService.doSomething();
txManager2 .commit(commonStatus);
ack.acknowledge();
}
In doSomething() I am just persisting an entity, upon debugging it is found that while saving the entity via Spring data repository, the transaction manager
determined in invokeWithinTransaction() of org.springframework.transaction.interceptor.TransactionAspectSupport is wrong, i.e. txManager1 is selected instead of txManager2, is it a configuration issue or am I missing something?
txManager1 configuration :
#Configuration
#EnableTransactionManagement
#PropertySource(value = {"classpath:application-${spring.profiles.active}.properties"})
#Profile({"development","production","qa"})
#EnableJpaRepositories(basePackages={"xxx.xxx.xxxx"},excludeFilters=#ComponentScan.Filter(type=FilterType.REGEX, pattern="xxx.xxx.xxxx.module2.*"))
public class JPAConfig1 {
#Value("${jndi.name}")
private String jndiName;
#Value("${hibernate.dialect}")
private String hibernateDialect;
#Value("${hibernate.show_sql}")
private String showSql;
#Value("${hibernate.format_sql}")
private String formatSql;
#Value("${hibernate.hbm2ddl.auto}")
private String hiberanteUpdate;
#Value("${javax.persistence.validation.mode}")
private String hibernateValidation;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory(MultiTenantConnectionProviderImpl tenantConnection, CurrentTenantIdentifierResolver currentTenantIdentifierResolver)
{
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emf.setJpaVendorAdapter(vendorAdapter);
emf.setJpaProperties(jpaProperties(tenantConnection, currentTenantIdentifierResolver));
emf.setPackagesToScan(new String[] {"xxx.xxx.xxxx"});
return emf;
}
private Properties jpaProperties(MultiTenantConnectionProviderImpl tenantConnection, CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",hibernateDialect);
properties.setProperty("hibernate.show_sql",showSql);
properties.setProperty("hibernate.format_sql",formatSql);
properties.setProperty("hibernate.hbm2ddl.auto",hiberanteUpdate);
properties.setProperty("javax.persistence.validation.mode",hibernateValidation);
properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, tenantConnection);
return properties;
}
#Bean
public CurrentTenantIdentifierResolver getCurrentTenantIdentifierResolver(TenantContext tenantContext) {
return new CurrentTenantIdentifierResolverImpl(tenantContext);
}
#Bean(name="tenantConnection")
public MultiTenantConnectionProviderImpl getMultiTenantConnectionProvider(TenantContext tenantContext) {
return new MultiTenantConnectionProviderImpl(false,tenantContext);
}
#Bean
#Primary
public PlatformTransactionManager transactionManager(EntityManagerFactory factory,ProducerFactory producerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(factory);
KafkaTransactionManager tm = new KafkaTransactionManager(producerFactory);
return new ChainedKafkaTransactionManager(tm,transactionManager);
}
#Bean
public TenantContext getTenantContext() {
return new TenantContextImpl();
}
}
txManager2 configuration :
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages="xxx.xxx.xxxx.module2",
entityManagerFactoryRef="common-factory",transactionManagerRef="common-tx")
#PropertySource(value = {"classpath:common-${spring.profiles.active}.properties"})
#Profile({"development","production","qa"})
public class JPAConfig2 {
#Value("${common.jndi.name}")
private String jndiName;
#Value("${common.hibernate.dialect}")
private String hibernateDialect;
#Value("${common.hibernate.show_sql}")
private String showSql;
#Value("${common.hibernate.format_sql}")
private String formatSql;
#Value("${common.hibernate.hbm2ddl.auto}")
private String hiberanteUpdate;
#Value("${common.javax.persistence.validation.mode}")
private String hibernateValidation;
#Bean(name="common-factory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(#Qualifier("common-ds") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan(new String[] {"xxx.xxx.xxxx.module2"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(jpaProperties());
em.setPersistenceUnitName("common");
return em;
}
#Bean("common-ds")
public DataSource dataSource() throws NamingException {
return (DataSource) new JndiTemplate().lookup(jndiName);
}
private Properties jpaProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",hibernateDialect);
properties.setProperty("hibernate.show_sql",showSql);
properties.setProperty("hibernate.format_sql",formatSql);
properties.setProperty("hibernate.hbm2ddl.auto",hiberanteUpdate);
properties.setProperty("javax.persistence.validation.mode",hibernateValidation);
return properties;
}
#Bean(name="common-tx")
public PlatformTransactionManager transactionManager(#Qualifier("common-factory") EntityManagerFactory factory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(factory);
return transactionManager;
}
}

HQL ingoring transaction

im building an Spring 4 + Hibernate 4 app. My config is this:
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(packagesDaoAnotaciones);
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
// ConfiguraciĆ³n del DataSource por el Servidor.
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
DataSource dataSource = dsLookup.getDataSource(environment.getRequiredProperty("jndi.datasource"));
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.generate_statistics", "true");
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
I have a Service with this method:
#Override
#Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void processThis() throws Exception {
List<String> myList = new ArrayList<>();
myList.add("1234567890");
myDao.update(myList,'01', "1234567890");
LOGGER.info("buahhhhhhhhhhhhhhhhhhhhhhh");
}
The Dao executes an HQL query like this:
#Override
public int update(List<String> data, String data1, String data2) {
StringBuffer hql = new StringBuffer();
hql.append("UPDATE MyTablenp SET np.field1 = :d1, field2= sysdate, field3= :d2, field4= sysdate, field5= null,field6= null WHERE np.data IN (:num)");
this.getSession().getTransaction().isActive();
Query query = this.getSession().createQuery(hql.toString());
query.setParameterList("num", data);
query.setParameter("d1", data1);
query.setParameter("d2", data2);
return query.executeUpdate();
}
When i execute this, i can see the data modified in the BBDD just after dao method ends, but the service method didnt finish yet, so its commiting the HQL without finish the transaction method. Do anyone knows how to avoid that commit and commit only when service method ends?
You should use the existing session opened by hibernate at the start of the annotated method proccessThis().
In your DAO do the following:
Remove this: this.getSession().getTransaction().isActive();
and instead get current session from the session factory(assuming you have extended HibernateDaoSupport):
Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();

createQuery is not valid without active transaction or invalid state, the connection object is closed

I have the following Java config file:
#Configuration
#ComponentScan(basePackages="com.blahblah")
#EnableWebMvc
#EnableTransactionManagement
#Import({ SecurityConfig.class })
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver getViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
dataSource.setUrl("jdbc:jtds:sqlserver://localhost:1433/VacationDB;instance=SQLEXPRESS");
dataSource.setUsername("bavarezul13");
dataSource.setPassword("Scholl1313.");
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(getDataSource());
sessionFactory.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
return sessionFactory;
}
#Bean(name = "transactionManager")
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory);
return txManager;
}
}
My DAO implementation is annotated #Transactional and I have a method like this:
#Repository(value="VacationDAOImplHibernate")
#Transactional
public class VacationDAOImplHibernate implements VacationDAO{
#Autowired
SessionFactory sessionFactory;
#Override
public VacationHibernate getVacation(int id) {
Session session = sessionFactory.getCurrentSession();
//Transaction tx = session.beginTransaction();
String hql = "from VacationHibernate v where v.id = :id";
#SuppressWarnings("unchecked")
List<VacationHibernate> listVacationHibernate = session.createQuery(hql).setParameter("id", id).list();
VacationHibernate vh = listVacationHibernate.get(0);
//tx.commit();
session.close();
return vh;
}
}
If I create a transaction and commit it, everything works normally. If not, I get the error:java.sql.SQLException: Invalid state, the Connection object is closed if I delete the following line from hibernate.cfg.xml: <property name="current_session_context_class">thread</property> or org.hibernate.HibernateException: createQuery is not valid without active transaction with that line in hibenrate.cfg.xml.
It wouldn't have been a problem to begin and commit the transaction by myself, but Transaction tx = session.beginTransaction(); takes 6 seconds!!!(I have no idea why)
Marius, you may also try setting up connection pooling in your application to improve database connection retrieval time, for example we use DBCP2 for connection pooling as the given example below
#Bean
public DataSource dataSource() {
final org.apache.commons.dbcp2.BasicDataSource dataSource = new org.apache.commons.dbcp2.BasicDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/myproject-db");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setInitialSize(2 * 5);
dataSource.setMaxTotal(2 * 50);
dataSource.setLogAbandoned(true);
dataSource.setMaxIdle(2);
dataSource.setMaxConnLifetimeMillis(3 * 60 * 1000); // Milliseconds (3 minutes)
dataSource.setPoolPreparedStatements(true);
return dataSource;
}
I found a solution to my errors: I deleted name="current_session_context_class">thread</property> in hibernate.cg.xml, so I had the error: java.sql.SQLException: Invalid state, the Connection object is closed as I said in my question.
Then I deleted session.close(); and the error went away.
Everything works now and Spring is managing the transaction but it also takes a lot of time to open it.
I suspect it might be a problem with the driver
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>

Spring Data JPA, cannot write to db from CommandLineRunner Bean

I'm following the Accessing Data with JPA guide and having an issues executing the CommandLineRunner Bean. The problem occurs when manually configuring my database component class. Basically, it works when I have the configuration as below and fails to write when the commented block is included.
Edit - With setShowSql enabled on the JpaVendorAdaptor, I can see select statements being by hibernate attempted, but no attempts at inserts. There are no errors on calling the repository to save, and the ID's are staying at 0 when checked after save.
I don't know if something is configured improperly or if I'm just completely missing a bean or something else.
#Component
public class RepoConfig {
#Value("${spring.datasource.driver-class-name}") private String driverClassName;
#Value("${spring.datasource.url}") private String url;
#Value("${spring.datasource.username}") private String username;
#Value("${spring.datasource.password}") private String password;
#Bean
DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
// #Bean
// public JpaVendorAdapter jpaVendorAdapter() {
// HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
// adapter.setDatabase(Database.SQL_SERVER);
// adapter.setDatabasePlatform("org.hibernate.dialect.SQLServer2012Dialect");
// adapter.setShowSql(true);
// adapter.setGenerateDdl(false);
// return adapter;
// }
//
// #Bean
// public EntityManagerFactory entityManagerFactory() {
// LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
// emfb.setJpaVendorAdapter(jpaVendorAdapter());
// emfb.setDataSource(dataSource());
// emfb.setPackagesToScan("model.package");
// emfb.afterPropertiesSet();
// return emfb.getObject();
// }
//
// #Bean
// public PlatformTransactionManager transactionManager() {
// JpaTransactionManager txManager = new JpaTransactionManager();
// txManager.setEntityManagerFactory(entityManagerFactory());
// return txManager;
// }
//
#Bean
Flyway flyway() {
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource());
flyway.migrate();
return flyway;
}
}

Resources