DataSource - Yash-777/LearnJava GitHub Wiki

Standalone Application stackpost

Here is a simple example of how to create and use a data source.

Web Application:

Tomcat provides a JNDI InitialContext implementation instance for each web application running under it, in a manner that is compatible with those provided by a Java Enterprise Edition application server. The Java EE standard provides a standard set of elements in the /WEB-INF/web.xml file to reference/define resources.

web.xmlweb-app_2_3.dtd configuration « Declare Your Resource Requirements

The following elements may be used in the web application deployment descriptor (/WEB-INF/web.xml) of your web application to define resources:

  • <env-entry> - Environment entry, a single-value parameter that can be used to configure how the application will operate.
  • <resource-ref> - Resource reference, which is typically to an object factory for resources such as a JDBC DataSource, a JavaMail Session, or custom object factories configured into Tomcat.
  • <resource-env-ref> - Resource environment reference, a new variation of resource-ref added in Servlet 2.4 that is simpler to configure for resources that do not require authentication information. Providing that Tomcat is able to identify an appropriate resource factory to use to create the resource and that no further configuration information is required, Tomcat will use the information in /WEB-INF/web.xml to create the resource.

References to Resources

Declaration of a reference to a JDBC connection factory that returns objects of type javax.sql.DataSource:

<resource-ref>
<description> Primary database </description>
<res-ref-name> jdbc/primaryDB </res-ref-name>
<res-type> javax.sql.DataSource </res-type>
<res-auth> Container </res-auth>
</resource-ref>

<res-type> is a fully-qualified class name of the resource factory. The variable can be assigned either Container or Application as a value.

If Container is specified, the web container handles the authentication before binding the resource factory to JNDI lookup registry. If Application is specified, the servlet must handle authentication programmatically. Different resource factories are looked up under a separate sub-context that describes the resource type, follows:

  • jdbc/ for a JDBC javax.sql.DataSource factory
  • mail/ for a JavaMail javax.mail.Session factory
  • url/ for a java.net.URL factory

Naming References and Binding Information JNDI Lookups and Their Associated References

JNDI Lookup Name Associated Reference
java:comp/env Application environment entries
java:comp/env/jdbc JDBC DataSource resource
java:comp/env/mail JavaMail Session Connection Factories
java:comp/env/url URL Connection Factories

context.xml configuration « Configure Tomcat's Resource Factory

If Tomcat is unable to identify the appropriate resource factory and/or additional configuration information is required, additional Tomcat specific configuration must be specified before Tomcat can create the resource. Tomcat specific resource configuration is entered in the elements that can be specified in either $CATALINA_BASE/conf/server.xml or, preferably, the per-web-application context XML file (META-INF/context.xml).

Tomcat JDBC: As a Resource in context.xml.

configuration driverClassName url
MySQL com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/javatest
Oracle 8i, 9i & 10g oracle.jdbc.OracleDriver jdbc:oracle:thin:@127.0.0.1:1521:mysid
PostgreSQL org.postgresql.Driver jdbc:postgresql://127.0.0.1:5432/mydb

Code Your Application's Use Of This Resource

A typical use of this resource environment reference might look like this:

Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/primaryDB");
Connection conn = ds.getConnection();
//etc.

Web application xml configuration.

<!-- context.xml -->
<Context>
    <Environment name="dev" value="jdbc/devdb" type="java.lang.String" override="false" />
    <Environment name="qa" value="jdbc/testdb" type="java.lang.String" override="false" />

    <Resource name="jdbc/devdb" type="javax.sql.DataSource" <!-- ... --> />
    <Resource name="jdbc/testdb" type="javax.sql.DataSource" <!-- ... --> />
</Context>
<!-- web.xml -->
<!-- JDBC DataSources (java:comp/env/jdbc) -->
<resource-ref>
	<description> Development database </description>
	<res-ref-name> jdbc/devdb </res-ref-name>
	<res-type> javax.sql.DataSource </res-type>
	<res-auth> Container </res-auth>
</resource-ref>
<resource-ref>
	<description> Testing database </description>
	<res-ref-name> jdbc/testdb </res-ref-name>
	<res-type> javax.sql.DataSource </res-type>
	<res-auth> Container </res-auth>
</resource-ref>

Initial Naming Context The naming support in Sun Java System Web Server is based primarily on J2SE 1.3, with a few added enhancements.When an application component creates the initial context by using InitialContext(), Sun Java System Web Server returns an object that serves as a handle to the Web application’s naming environment. This object in turn provides sub-contexts for the java:comp/env namespace. Each Web application gets its own namespace java:comp/env name space is allotted to each Web application and objects bound in one Web application’s namespace do not collide with objects bound in other Web applications.

Strng JNDI_Lookup_Name = "java:comp/env/";

String ResourceName1 = "jdbc/devdb", ResourceName2 = "jdbc/testdb";
String env1 = "dev", env2 = "test";

InitialContext initContext = new InitialContext();

// context lookup "java:comp/env/jdbc/devdb"
DataSource ds = initContext.lookup(JNDI_Lookup_Name + ResourceName1);

// context environment lookup
Context envContext  = (Context)initContext.lookup(JNDI_Lookup_Name);
DataSource ds = (DataSource)envContext.lookup(ResourceName1);

// Environment resource name lookup
String env_resourceName = (String)initialContext.lookup(JNDI_Lookup_Name + env1);
DataSource ds = (DataSource)initialContext.lookup(JNDI_Lookup_Name + env_resourceName);

Connection conn = ds.getConnection();

Database URLs are strings. The complete URL syntax is:

jdbc:oracle:driver_type:[username/password]@database_specifier

jdbc:<DB>:<drivertype>:<HOST>:<TCP/IP PORT>:<dataBaseName>
jdbc:oracle:thin:@localhost:1521:myDBName
jdbc:mysql://localhost:3306/myDBName

The first part of the URL specifies which JDBC driver is to be used. The supported driver_type values are thin, oci, and kprb.

  • Oracle Net connection descriptor support thin driver.
String url="jdbc:oracle:thin:@(DESCRIPTION=
	  (LOAD_BALANCE=on)
	(ADDRESS_LIST=
	  (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521))
	 (ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521)))
	 (CONNECT_DATA=(SERVICE_NAME=service_name)))"
  • Thin-style service name
"jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename"

SERVICE_NAME: Use the parameter SERVICE_NAME to identify the Oracle9i or Oracle8 database service to access. Set the value to a value specified by the SERVICE_NAMES parameter in the initialization parameter file.

SID: Use the parameter SID to identify the Oracle8 database instance by its Oracle System Identifier (SID). If the database is Oracle9i or Oracle8, use the SERVICE_NAME parameter rather than the SID parameter.

Embed this parameter under the CONNECT_DATA parameter.

Example

net_service_name= 
 (DESCRIPTION=
   (ADDRESS=...)
   (ADDRESS=...)
   (CONNECT_DATA=
    (SID=sales)))


accessToUnderlyingConnectionAllowed

<Resource name="jdbc/dbName" type="javax.sql.DataSource"
    username="scott" password="tiger" 
    url="jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)
        (ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=host))(CONNECT_DATA=(SID=service_id_applets)))"
    driverClassName="oracle.jdbc.driver.OracleDriver" maxTotal="20" maxIdle="10"
    maxWaitMillis="5000" minEvictableIdleTimeMillis="300000"
    timeBetweenEvictionRunsMillis="600000" validationInterval="600000"
    validationQuery="select 1 from dual" testOnBorrow="true" auth="Container"
    accessToUnderlyingConnectionAllowed="true" />

If true the raw physical connection to the database can be accessed using the following construct:

Connection conn = ds.getConnection();
Connection rawConn = ((DelegatingConnection) conn).getInnermostDelegate();
...
conn.close()

Default is false, because misbehaving programs can do harmfull things to the raw connection shuch as closing the raw connection or continuing to use the raw connection after it has been assigned to another logical connection. Be careful and only use when you need direct access to driver specific extensions.

NOTE: Do NOT close the underlying connection, only the original logical connection wrapper.


DataSourceConfiguration with @EnableTransactionManagement, @EnableJpaRepositories
package com.github.yash777.myworld.db.config;

import java.util.HashMap;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "rdbmsEntityManager",
  transactionManagerRef = "transactionManager", // rdbmsTransactionManager
  basePackages = { "com.github.yash777.repositories", "com.github.yash777.*.repositories" }
)
/*
Exception in thread "main" java.lang.IllegalStateException: No CacheResolver specified, and no bean of type CacheManager found. Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:277)
at com.yash.db.config.DependencyScanner.main(DependencyScanner.java:40)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cache.CacheManager' available
*/
//@org.springframework.cache.annotation.EnableCaching

//@ConditionalOnProperty(value = "datasourceType", havingValue = "RDBMS_MySQL", matchIfMissing = false)
//Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jpaBaseDaoImpl': Unsatisfied dependency expressed through field 'dataSource': No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier("dataSource")}
//Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class
public class DataSourceConfig {
    //ehcache = Suppressed: java.lang.ClassNotFoundException: org.hibernate.cache.ehcache.EhCacheRegionFactory
    static String cachingProvider = "jcache"; // ehcache | jcache
    static boolean isHardCodedProps = true;
    
    {
        System.out.println("----- DataSourceConfig -----"); // myworld-db dependency added in api module.
    }
    static String entitiesPackage = "com.github.yash777.myworld";
    final static String dataSourcePrefix = "app.datasource.myapp";
    
    @Autowired
    Environment env;
    
    @Bean @Primary
    @ConfigurationProperties(prefix = "app.datasource.myapp")
    public DataSourceProperties dsproDataSourceProperties() {
        return new DataSourceProperties();
    }
    
    /*
<dependency>
<groupId>org.apache.tomcat:tomcat-jdbc</artifactId>
<version>${tomcat.version}</version>
</dependency>
     */
    @Bean(name = "dataSource")
    public DataSource tomcatDataSource() {
        org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/flyway_demo?createDatabaseIfNotExist=true"); //("jdbc:mysql://localhost:3306/mydatabase");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUsername("root"); //("user");
        dataSource.setPassword("root"); //("password");
        return dataSource;
    }
/*
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>${hikaricp.version}</version>
</dependency>
 */
    @Bean(name = "dataSource") //@Primary
    public DataSource getHikariCP() {
        System.out.println("Creating dsproDataSource Bean......................");
        HikariConfig hikariConfig = new HikariConfig();
        
        if (isHardCodedProps) {
            hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/myappschema?createDatabaseIfNotExist=true"); //("jdbc:mysql://localhost:3306/mydatabase");
            hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
            hikariConfig.setUsername("root"); //("user");
            hikariConfig.setPassword("root"); //("password");
            
            hikariConfig.setMaximumPoolSize(10); // Adjust based on your needs      100   / 10
            hikariConfig.setConnectionTimeout(30000); // Increase timeout if needed 10000 / 30000
            hikariConfig.setIdleTimeout(600000); // Adjust idle timeout             10000 / 600000
            hikariConfig.setMaxLifetime(1800000); // Adjust max lifetime            1000  / 1800000
            hikariConfig.setKeepaliveTime(1000); // MaxLifetime                     1000
            hikariConfig.setMinimumIdle(30);
        } else {
            hikariConfig.setJdbcUrl(env.getProperty("app.datasource.myapp.url",String.class));
            hikariConfig.setDriverClassName(env.getProperty("app.datasource.myapp.driver-class-name",String.class));
            hikariConfig.setUsername(env.getProperty("app.datasource.myapp.username",String.class));
            hikariConfig.setPassword(env.getProperty("app.datasource.myapp.password",String.class));
            
            hikariConfig.setMaximumPoolSize(env.getProperty("app.datasource.myapp.hikari.maximum-pool-size", Integer.class));
            hikariConfig.setConnectionTimeout(env.getProperty("app.datasource.myapp.hikari.connection-timeout", Long.class)); 
            hikariConfig.setIdleTimeout(env.getProperty("app.datasource.myapp.hikari.idle-timeout", Long.class)); 
            hikariConfig.setMaxLifetime(env.getProperty("app.datasource.myapp.hikari.max-lifetime", Long.class)); 
            hikariConfig.setKeepaliveTime(env.getProperty("app.datasource.myapp.hikari.max-lifetime", Long.class));
            hikariConfig.setMinimumIdle(env.getProperty("app.datasource.myapp.hikari.minimum-idle", Integer.class));
        }
        
        HikariDataSource dataSource = new HikariDataSource(hikariConfig);
        return dataSource;
        // return dsproDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
    
    @Bean @Primary
    public LocalContainerEntityManagerFactoryBean rdbmsEntityManager() {
        System.out.println("Creating rdbmsEntityManager Bean......................");
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource( getHikariCP() );
        em.setPackagesToScan( entitiesPackage );
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<>();
        //properties.put("hibernate.allow_update_outside_transaction",true);
        
/*
 * 
Caused by: java.lang.Throwable
    at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass(AggregatedClassLoader.java:209) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
Suppressed: java.lang.ClassNotFoundException: org.hibernate.dialect.MySQL5Dialect

Caused by: java.lang.ClassNotFoundException: Could not load requested class : org.hibernate.dialect.MySQL5Dialect
//properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
 * 
 * HHH90000026: MySQL8Dialect has been deprecated; use org.hibernate.dialect.MySQLDialect instead
 * o.h.o.deprecation : HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
 */
        properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); // update
//        properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); // org.hibernate.dialect.MySQLDialect
        // Other Hibernate properties
//        properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
//        properties.put("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
        
// Cache configuration (Ensure that Ehcache is compatible with Hibernate 6.x)
// https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#configurations-cache
properties.put("hibernate.cache.use_second_level_cache", "true");
properties.put("hibernate.cache.use_query_cache", "true");
if (cachingProvider.equals("ehcache")) { 
// https://www.digitalocean.com/community/tutorials/hibernate-ehcache-hibernate-second-level-cache
// https://www.ehcache.org/documentation/2.8/integrations/hibernate.html#enable-second-level-cache-and-query-cache-settings
// Either a shortcut name (e.g. jcache, ehcache) or the fully-qualified name of the RegionFactory implementation class.
    properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
    //properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");
// n.s.e.c.ConfigurationFactory : No configuration found. Configuring ehcache from ehcache-failsafe.xml  found in the classpath: jar:file:/C:/Users/ymerugu/.m2/repository/net/sf/ehcache/ehcache/2.10.9.2/ehcache-2.10.9.2.jar!/ehcache-failsafe.xml
    properties.put("net.sf.ehcache.configurationResourceName", "ehcache2.xml"); // EHCache configuration file location
} else { // EhcacheManager - Eh107CacheManager
    //org.hibernate.cache.internal.RegionFactoryInitiator -- HHH000025: Second-level cache region factory [org.hibernate.cache.jcache.internal.JCacheRegionFactory]
    properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.jcache.internal.JCacheRegionFactory");
    properties.put("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider");
    properties.put("hibernate.javax.cache.uri", "ehcache3-jsr107.xml");
}
        
/*
# HHH020100: The Ehcache second-level cache provider for Hibernate is deprecated.  See https://hibernate.atlassian.net/browse/HHH-12441 for details.
# Hibernate configuration for Ehcache integration
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true

hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.cache.ehcache.config_file=classpath:ehcache.xml # (Ensure this file is correctly configured)

==============================================
properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");

o.h.Version                              : HHH000412: Hibernate ORM core version 6.5.2.Final
2024-12-22T21:34:19.040+05:30 ERROR 22360 --- [           main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.cache.spi.RegionFactory] due to: Caching was explicitly requested, but no RegionFactory was defined and there is not a single registered RegionFactory
2024-12-22T21:34:19.042+05:30  WARN 22360 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rdbmsEntityManager' defined in class path resource [com/yash/db/config/DataSourceConfig.class]: Unable to create requested service [org.hibernate.cache.spi.RegionFactory] due to: Caching was explicitly requested, but no RegionFactory was defined and there is not a single registered RegionFactory
2024-12-22T21:34:19.043+05:30  INFO 22360 --- [           main] c.z.h.HikariDataSource                   : HikariPool-1 - Shutdown initiated...
2024-12-22T21:34:19.080+05:30  INFO 22360 --- [           main] c.z.h.HikariDataSource                   : HikariPool-1 - Shutdown completed.
==============================================

hibernate.cache.region.factory_class=org.hibernate.cache.jcache.internal.JCacheRegionFactory
hibernate.javax.cache.uri=ehcache.xml
hibernate.javax.cache.provider=org.ehcache.jsr107.EhcacheCachingProvider

==============================================
//        properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");

o.h.Version                              : HHH000412: Hibernate ORM core version 6.5.2.Final
2024-12-22T21:25:53.584+05:30  INFO 35220 --- [           main] o.h.c.i.RegionFactoryInitiator           : HHH000025: Second-level cache region factory [org.hibernate.cache.jcache.internal.JCacheRegionFactory]
2024-12-22T21:25:54.979+05:30  INFO 35220 --- [           main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
2024-12-22T21:25:55.215+05:30  WARN 35220 --- [           main] o.h.o.deprecation                        : HHH90000025: MySQL8Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2024-12-22T21:25:55.218+05:30  WARN 35220 --- [           main] o.h.o.deprecation                        : HHH90000026: MySQL8Dialect has been deprecated; use org.hibernate.dialect.MySQLDialect instead
2024-12-22T21:25:56.617+05:30  WARN 35220 --- [           main] o.h.o.cache                              : HHH90001006: Missing cache[default-update-timestamps-region] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.
2024-12-22T21:25:56.848+05:30  INFO 35220 --- [           main] o.e.c.EhcacheManager                     : Cache 'default-update-timestamps-region' created in EhcacheManager.
2024-12-22T21:25:56.875+05:30  WARN 35220 --- [           main] o.h.o.cache                              : HHH90001006: Missing cache[default-query-results-region] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.
2024-12-22T21:25:56.881+05:30  INFO 35220 --- [           main] o.e.c.EhcacheManager                     : Cache 'default-query-results-region' created in EhcacheManager.
2024-12-22T21:25:56.915+05:30  WARN 35220 --- [           main] o.h.o.cache                              : HHH90001006: Missing cache[com.yash.db.entities.Address] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.
2024-12-22T21:25:56.920+05:30  INFO 35220 --- [           main] o.e.c.EhcacheManager                     : Cache 'com.yash.db.entities.Address' created in EhcacheManager.
2024-12-22T21:25:58.452+05:30  INFO 35220 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
Hibernate: 
    alter table User 
       modify column Definition text not null */
        
        em.setJpaPropertyMap(properties);
        return em;
    }
    
    @Bean @Primary
    public PlatformTransactionManager transactionManager() {
        //public PlatformTransactionManager rdbmsTransactionManager() {
        System.out.println("Creating Transaction Mangaer..................");
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory( rdbmsEntityManager().getObject() );
        return transactionManager;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate() {
        System.out.println("Creating JdbcTemplate ..................");
        return new JdbcTemplate( getHikariCP() );
    }
    @Bean
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
        System.out.println("Creating NamedParameterJdbcTemplate ..................");
        return new NamedParameterJdbcTemplate( getHikariCP() );
    }
}
datasourceType = RDBMS_MySQL

# Show SQL in console for debugging
# spring.jpa.show-sql is more general and works across various JPA providers, while hibernate.show_sql is specific to Hibernate.
#hibernate.show_sql=true   - is a more direct Hibernate configuration, so if you're using Spring with Hibernate, both will have the same effect, but it's good practice to use spring.jpa.show-sql=true in Spring Boot applications.
spring.jpa.show-sql=true
#hibernate.format_sql=true
# Optionally, you can also log the Hibernate format
spring.jpa.properties.hibernate.format_sql=true

# Hibernate DDL mode
#spring.jpa.hibernate.ddl-auto = update
hibernate.hbm2ddl.auto = update
#hibernate.hbm2ddl.auto=validate


#logging.level.org.springframework.beans.factory=DEBUG
#logging.level.org.springframework.context.annotation=DEBUG
#logging.level.org.springframework=DEBUG
logging.level.org.springframework.orm.jpa=DEBUG
logging.level.org.hibernate=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

#spring.batch.initialize-schema=ALWAYS
#spring.batch.job.create-context=true

# Default Configuration (Spring Boot Auto Configuration) - Spring Boot configures a DataSource bean if you have database properties set
#spring.datasource.url= jdbc:mysql://localhost/javainusedb?createDatabaseIfNotExist=true&useSSL=false
#spring.datasource.username= root
#spring.datasource.password= root
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#
#spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQLDialect
#spring.jpa.hibernate.ddl-auto= update
#spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
#spring.jpa.show-sql=true
# MySQL JDBC driver class name and Dialect
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
#spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JDBC URL to connect to MySQL
app.datasource.myapp.url=jdbc:mysql://localhost/myappschema?createDatabaseIfNotExist=true
app.datasource.myapp.username=root
app.datasource.myapp.password=root

app.datasource.dspro.driver-class-name=com.mysql.cj.jdbc.Driver
### Dspro Database Connection Pool Details
app.datasource.myapp.hikari.connection-timeout=10000
app.datasource.myapp.hikari.idle-timeout=10000
app.datasource.myapp.hikari.maximum-pool-size=50
app.datasource.myapp.hikari.minimum-idle=30
app.datasource.myapp.hikari.max-lifetime=1000
app.datasource.myapp.hikari.keepalive-time=1000
app.datasource.myapp.hikari.pool-name=DsproHikariPool

In a Spring Boot application using @EnableBatchProcessing, how can I configure Spring Batch to use a separate transaction manager and DataSource for batch jobs, instead of the main application DataSource and its transaction manager?

@Configuration
@EnableBatchProcessing
public class CustomBatchConfigJpaTransactionManager extends DefaultBatchConfigurer {
   @Autowired
   private LocalContainerEntityManagerFactoryBean rdbmsEntityManager;
   private JpaTransactionManager transactionManager;
   @Override
   public PlatformTransactionManager getTransactionManager() {
      if (this.transactionManager == null) {
         JpaTransactionManager transactionManager = new JpaTransactionManager();
         if (this.rdbmsEntityManager != null) {
            transactionManager.setEntityManagerFactory(this.rdbmsEntityManager.getObject());
         }
         this.transactionManager = transactionManager;
         System.out.println("transactionManager.........." + transactionManager);
      } else if (this.transactionManager != null && this.rdbmsEntityManager != null) {
         this.transactionManager.setEntityManagerFactory(this.rdbmsEntityManager.getObject());
      }
      return this.transactionManager;
   }
}
⚠️ **GitHub.com Fallback** ⚠️