Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HikariCP DataSource #418

Closed
brettwooldridge opened this issue Mar 4, 2014 · 8 comments
Closed

Add support for HikariCP DataSource #418

brettwooldridge opened this issue Mar 4, 2014 · 8 comments
Assignees
Labels
type: enhancement A general enhancement
Milestone

Comments

@brettwooldridge
Copy link
Contributor

First, thanks for the excellent project. I noticed you are using commons-dbcp. Even Apache Tomcat has officially abandoned commons-dbcp in favor of their own pool. While there are many pool choices out there, I invite you to check-out our pool, HikariCP. Not just for performance, but correctness. HikariCP is in wide use (as you can tell by our "Stars"), and active development, with over 2500 downloads from maven central repository in just the past month.

@philwebb
Copy link
Member

philwebb commented Mar 4, 2014

Thanks for the information. We currently only use commons-dbcp as a last resort, we have been recommending the Tomcat pool whenever possible.

It looks like HikariCP required Java 1.7. This might be a showstopper for us since we are currently trying to remain Java 1.6 compatible. Having said that, it might be nice if this were an auto-configuration option so that if people choose to use it, it just works.

If you are interested in submitting a pull-request take a look at the DataSourceAutoConfiguration class, there is also this blog post which should help.

I'm afraid, even with a pull-request, this is something that won't make the 1.0.0 since we now at the RC stage and we are trying to stabilize things.

@brettwooldridge
Copy link
Contributor Author

The next release of HikariCP has been back ported to Java6, it will be published later the week. I'll take look at the DataSourceAutoConfiguration class, and put together a pull request.

@philwebb
Copy link
Member

philwebb commented Mar 4, 2014

Cheers. BTW I previously read your Down The Rabbit Hole article and I have been meaning to take a closer look at the project.

@brettwooldridge
Copy link
Contributor Author

I've forked spring-boot and started looking at DataSourceAutoConfiguration, and I have a question. It appears that NonEmbeddedDatabaseCondition imposes the requirement for a driver class:

String driverClassName = getDriverClassName(context.getEnvironment(),
                                            getDataSourceClassLoader(context));
if (driverClassName == null) {
    return ConditionOutcome.noMatch("no database driver");
}

But one of the points of a JDBC DataSource was to get away from requiring explicitly loading a driver class. Additionally, it appears that NonEmbeddedDatabaseCondition requires a JDBC URL:

String url = getUrl(context.getEnvironment(), context.getClassLoader());
if (url == null) {
    return ConditionOutcome.noMatch("no database URL");
}

Again, the JDBC DataSource was a move away from URL-based connection configuration. HikariCP uses neither.

Quoting variously from Oracle's DataSource tutorial:

This section covers DataSource objects, which are the preferred means of getting a connection to a
data source.
...
Deploying a DataSource object consists of three tasks:
 1. Creating an instance of the DataSource class
 2. Setting its properties
 3. Registering it with a naming service that uses the Java Naming and Directory Interface (JNDI) API
...

In the section Advantages of DataSource Objects:

Because of its properties, a DataSource object is a better alternative than the DriverManager
class for getting a connection. Programmers no longer have to hard code the driver name or
JDBC URL in their applications, which makes them more portable. Also, DataSource
properties make maintaining code much simpler.

Any advice on how to approach changes to DataSourceAutoConfiguration/NonEmbeddedDatabaseCondition such that they do not require the use of a driver class or URL-based connection?

@dsyer
Copy link
Member

dsyer commented Mar 5, 2014

Sorry I don't follow. Can you paste a link to some HikariCP code that would elucidate? An application doesn't need to know JDBC connection details if it gets a DataSource from a registry (like JNDI for example), but the creator of the registry does, surely (and that is the role Spring is playing here). In a standalone application normally there is no JNDI provider, so for portability Spring users prefer to inject the JDBC connection properties.

@brettwooldridge
Copy link
Contributor Author

I was referring not application-level code but instead submitting, as Phil suggested, a pull request for an auto-configuration class to integrate HikariCP into spring-boot. The suggestion was to look at ``DataSourceAutoConfiguration`. The following are two examples of configuring a HikariCP DataSource:

HikariDataSource ds = new HikariDataSource();
ds.setMaximumPoolSize(100);
ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
ds.addDataSourceProperty("url", "jdbc:mysql://localhost/database");
ds.addDataSourceProperty("user", "bart");
ds.addDataSourceProperty("password", "51mp50n");

or using a configuration object (HikariConfig) and properties file:

HikariConfig config = new HikariConfig("hikari.properties");
HikariDataSource ds = new HikariDataSource(config);

where hikari.properties contains something like:

dataSourceClassName=org.postgresql.ds.PGSimpleDataSource
dataSource.user=test
dataSource.password=test
dataSource.databaseName=mydb
dataSource.serverName=localhost

Notice in both cases, there is no reference to a Driver class and there is no JDBC connection URL (DataSources don't need them).

So, turning back to DataSourceAutoConfiguration et al, I see there is class TomcatDataSourceConfiguration which inherits from AbstractDataSourceConfiguration, which offers only url and driverClassName but no dataSourceClassName. DataSourceAutoConfiguration itself contains an inner-class, NonEmbeddedDatabaseCondition, from which another inner-class TomcatDatabaseCondition inherits. NonEmbeddedDatabaseCondition contains a method getMatchOutcome() which it overrides from SpringBootCondition. Presumably to create an auto-configuring DataSource I am supposed to extend from NonEmbeddedDatabaseCondition. But the getMatchOutcome() in that class throws an exception if getDriverClassName() returns null, or in turn if getUrl() returns null.

Even if I override getMatchOutcome(), I don't see how proper configuration can be passed into my DataSource given that it does not operate based off of a driver class. I think the assumption here is that all connection pools operate off of driver classes and URLs, but that notion is stuck back in 2004.

I'm just looking for some guidance here as to what and where to make precise changes so as to accomplish the task of integrating HikariCP along with minimizing the change to existing code.

@brettwooldridge
Copy link
Contributor Author

@philwebb We have just released HikariCP 1.3.2 with Java 6 support (formerly only Java 7). I know it is "late" in the release cycle, but I would recommend reading our competitive pool analysis, especially if you are going into production with Tomcat-jdbc. Tomcat has issues that cannot be mitigated though configuration, but it also has issues that can be mitigated and you might be wise to do so.

@brettwooldridge
Copy link
Contributor Author

Thanks for the support of HikariCP. Thought you'd might be interested in this real-world deployment result vs BoneCP.

@dsyer dsyer removed the in progress label May 30, 2014
mdeinum pushed a commit to mdeinum/spring-boot that referenced this issue Jun 6, 2014
We still prefer Tomcat if it is available (that can change
if the community asks loudly enough). Hikari is supported
via the same spring.datasource.* properties as Tomcat (and
DBCP), with some modifications:

* The validation and timeout settings are not as fine-grained
in Hikari, so many of them will simply be ignored. The most
common options (url, username, password, driverClassName) all
work as expected.

* The Hikari team recommends using a vendor-specific DataSource
via spring.datasource.dataSourceClassName and supplying it with
Properties (spring.datasource.hikari.*).

Hikari prefers the JDBC4 isValid() API (encapsulates vendor-
specific queries) which is probably a good thing, but we
haven't provided any explicit support or testing for that yet.

Fixes spring-projectsgh-418
XuefengWu added a commit to XuefengWu/spring-boot-dynamic-database that referenced this issue Jan 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants