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
Related
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
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();
}
How to bind a JDBC datasource to JNDI context java:comp/env/jdbc only using code-based approach.
We need to write resource-ref in the web.xml for binding a dataSource to JNDI local context java:comp/env/jdbc.
But I want to use only org.springframework.web.context.AbstractContextLoaderInitializer instead of web.xml(the old approach).
We know the method InitialContext#createSubcontext. But some application servers(e.g. Websphere) do not accept to edit the context java:comp/env/jdbc/.
Any solutions?
Versions:
Spring 4.0.7
Servlet 3.0
You could try a full programmatic approach using Spring's SimpleNamingContextBuilder:
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
DataSource ds = new DriverManagerDataSource(...);
builder.bind("java:comp/env/jdbc/myds", ds); // you control the datasource
builder.activate();
It's mainly there for test-purposes. If you choose to use it then you need to provide your own connection pool (e.g. Apache's Jakarta Commons DBCP).
I once used for testing when I deployed to cloudbees. see this blogpost
This works in "plain" Tomcat. I don't have a EE server to test with, but you could try it and see what happens (I guess the JNDI binding name has to be unique to the server though).
What is your application server?
See if this helps.
How to use JNDI DataSource provided by Tomcat in Spring?
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.
My WAR application is deployed to Amazon Elastic Beanstalk. They don't support JNDI, but I need it for JPA and unit tests. What JNDI context factory I can use as a workaround? I need a simple open source solution, that would allow me to configure entire factory through jndi.properties. I tried GuiceyFruit, but looks like it doesn't allow data source configuration inside one file. Any suggestions?
ps. OpenEJB will work, but it's an overkill for such a simple task
Try Simple-JNDI. It gives you an in-memory implementation of a JNDI Service and allows you to populate the JNDI environment with objects defined in property files. There is also support for loading datasources or connection pools configured in a file.
To get a connection pool you have to create a file like this:
type=javax.sql.DataSource
driver=com.sybase.jdbc3.jdbc.SybDriver
pool=myDataSource
url=jdbc:sybase:Tds:servername:5000
user=user
password=password
In your application you can access the pool via
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("path/to/your/connectionPool");
You can find more about it at https://github.com/h-thurow/Simple-JNDI.