I have a Spring Boot micro service that connects to several databases through a JDBC connection using JDBCTemplate:
#Bean(name = "mysqlJdbcTemplate")
public JdbcTemplate jdbcTemplate(#Qualifier("mysqlDb") DataSource dsMySQL) {
return new JdbcTemplate(dsMySQL);
}
I have different template for each database and then rest template controller that chooses the right template to use depending on the parameters passed in the request.
I read the documentation, however it's not clear:
Is a connection pool used out of the box or I need to specify it through configuration?
In this case is a connection pool used for each JDBCTemplate?
Spring Boot will try to load available connection pool for your DataSource:
Spring Boot uses the following algorithm for choosing a specific implementation:
We prefer HikariCP for its performance and concurrency. If HikariCP is available, we always choose it.
Otherwise, if the Tomcat pooling DataSource is available, we use it.
If neither HikariCP nor the Tomcat pooling datasource are available and if Commons DBCP2 is available, we use it.
If you use the spring-boot-starter-jdbc or spring-boot-starter-data-jpa “starters”, you automatically get a dependency to HikariCP.
You can bypass that algorithm completely and specify the connection pool to use by setting the spring.datasource.type property. This is especially important if you run your application in a Tomcat container, as tomcat-jdbc is provided by default.
Additional connection pools can always be configured manually. If you define your own DataSource bean, auto-configuration does not occur.
Example of defining your own bean:
#Bean
public DataSource dataSource() throws PropertyVetoException {
return MyDataSourceHolder.getDataSource();
}
Related
I'm configuring HikariCP for Spring Boot application, the database is Postgresql.
The documentation says:
"We recommended using dataSourceClassName instead of jdbcUrl, but either is acceptable."
However, the next line says:
"Note: Spring Boot auto-configuration users, you need to use jdbcUrl-based configuration."
If we use jdbcUrl-based configuration and specify dataSourceClassName then jdbcUrl will be ignored, if we don't specify data source - HikariDataSource will be created. So they recommend using HikariDataSource for Spring Boot apps.
If we use dataSourceClassName - it will be created with given properties (in my case it is PGSimpleDataSource with its ancestor BaseDataSource).
Both these configurations work for me.
So, my questions are:
What is the difference between HikariDataSource and PGSimpleDataSource (or any other recommended)?
Why it is recommended to use jdbcUrl-based configuration (and thus HikariDataSource) in Spring Boot?
HikariCP is a connection pool, and a very good one. We've been using it in several projects in production and it's fast and just works.
If you want to use HikariCP you use HikariDataSource. Spring Boot has started to use it as a default and recommends it (for the same reasons: it's fast and solid).
If you just use the default configuration with spring.datasource.url, it will use HikariCP and should work out-of-the-box.
However, when you manually configure your datasource(s), there is a small issue with Spring Boot 2 and HikariCP. HikariCP expects jdbcUrl or dataSourceClassName, but the Spring Boot configuration property uses url.
See the documentation or this question for that.
In Spring Boot I can pass properties which will be picked for auto configuration:
spring.ldap.url
spring.ldap.username
spring.ldap.password
Is there any spring.ldap.* property to set pooled=true to avoid using explicit LdapTemplate config?
LdapContextSource contextSource = new LdapContextSource();
contextSource.setPooled(true);
According to the Appendix that lists all of the Spring Boot properties, no. I also looked at the LdapProperties class which stores these values at runtime and didn't see anything in there that would help with pooling. I suspect you'll have to keep doing this manually.
Perhaps file a PR on them? They seem open to adding things if there is a need in the community.
You can set ldap pool properties with JVM parameters. You specify them when launching your application.
For example:
-Dcom.sun.jndi.ldap.connect.pool.maxsize=10
-Dcom.sun.jndi.ldap.connect.pool.prefsize=5
-Dcom.sun.jndi.ldap.connect.pool.timeout=300000
Everything that I have read on this recommends that configuration be done using the PoolingContextSource. The LDAP authentication process requires a two-stage process that is problematic. The below is from the blog of Mattias Hellborg Arthursson, a Spring LDAP guru.
Built-in JNDI Connection Pooling
The pooled property of ContextSource has previously defaulted to true,
enabling the built-in Java LDAP connection pooling by default. However
the built-in LDAP connection pooling suffers from several deficiencies
(most notable there is no way of doing connection validation and
configuration is cumbersome), which is why we decided to change the
default to false . If you require connection pooling we strongly
recommend using the Spring LDAP PoolingContextSource instead.
https://blog.jayway.com/2008/10/27/whats-new-in-spring-ldap-13/
https://docs.spring.io/spring-ldap/docs/1.3.2.RELEASE/reference/html/pooling.html
is it possible to intercept the connection pooling mechanism of a DataSource in a JEE container?
For (un)setting some information on the connection's context I'm searching for a way to intercept the pooling mechanism so that I know when and which connection is put back into the pool.
So does anyone know a (common) way to do this?
Some additional info:
The application runs on Wildfly
Using Hibernate for ORM
The option connection-listener in datasource configuration can be the solution.
connection-listener:
An org.jboss.jca.adapters.jdbc.spi.listener.ConnectionListener that
provides a possible to listen for connection activation and
passivation in order to perform actions before the connection is
returned to the application or returned to the pool
You can create a custom implementation of org.jboss.jca.adapters.jdbc.spi.listener.ConnectionListener and deploy it as a module to do that you want.
How I can create web application project which is loading the jndi datasource set in the server configuration? I want to make the web application independent from the server and the database. Is it possible.
You create the DataSource in your web/application server and expose it through JNDI
You configure the following hibernate property:
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyDataSource</p>
This way the application is decoupled from the JNDI provider. Even the JNDI url can be configured using a Maven property, so switching to an application server (that uses a different JNDI resource pattern) is just a mater of adding a new Maven profile.
One better approach is to set up the DataSource in your application configuration.
#Autowired
private DataSource dataSource;
...
properties.put("hibernate.connection.datasource", dataSource);
This way you can use any connection pooling framework, like the fastest connection pooling framework, HikariCP.
You can even set up DataSource proxies, like:
datasource-proxy, to log SQL queries with PreparedStatement parameters
FlexyPool, to monitor connection pooling usage and adjust the pool size using adapting startegies
In a java application, If we want to use javax.sql.DataSource instead of java.sql.DriverManager to get connections, which approach would be better to create DataSource and WHY?
Create DataSource in the application itself at the application startup time
or
Configure DataSource in the application server and get it via JNDI
Well, it actually depends upon the requirement. You can take this as a general rule.If you have multiple applications and sharing the same DataSource, then it can be a good choice to configure the DataSource in the server. Otherwise, if this is the only application uses the DataSource, then you can have it in the application level itself.