Instantiating a JdbcTemplate from a java.sql.Connection - java

I want to obtain a JdbcTemplate in my Java code. I've already got a working java.sql.Connection. To create a new JdbcTemplate it would normally need an instance of the javax.sql.DataSource interface.
Is it somehow possible to obtain a new JdbcTemplatefrom an existing java.sql.Connection?

Technically, you can, using SingleConnectionDataSource
new JdbcTemplate(new SingleConnectionDataSource(connection, false))
However, this is not quite advisable, unless for unit-tests for example.
You'd better use a full-featured DataSource and wire things using spring.

No, JdcbTemplate is a Spring class; Connection is part of the JDK. Connection knows nothing about JdbcTemplate.
The way to do it is to add a JdbcTemplate bean in your Spring app context; then inject it into the classes that need it declaratively.

Related

JPA Persistence with Jersey without Injection

I'm developing a REST API with jersey. Now I have to persist the entities with JPA and as I learned in university I "openend" a DB Connection with the following code:
EntityManagerFactory factory = javax.persistence.Persistence.createEntityManagerFactory("LootDB");
EntityManager em = factory.createEntityManager();
I'm using the code above in EVERY RESOURCE. But I think this is a bad design. Because I don't know about Spring and dependency injection, I have to create the persistence instances manually.
Is there something wrong? In the database I can observe just 2 openened connections and I never get concurrency issues.
any help is appreciated...
You can define a class which spring bean scope is singleton.For accessing that class instance use #Autowired annotation.After that you can access the factory instance with it in everywhere.

Abstract class variable with spring

I am using spring and Hibernate and Dao design pattern for the my project, In my GenericDaoImpl(Abstract class) class has "tenentId", I want to set the "tenentId" when use login to the System. My other DaoImpl classes extends from GenericDaoImpl, so I need to set the tenentId(It's define in GenericDaoImpl) user login time and reset the "tenentId" when user log out.
What is the best way to do this?
In my test cases I tried #Autowired the "GenericDaoImpl" but I couldn't do that, It throws an exception telling, org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type. I know the problem now,
(We can't create instance of abstract classes,if use tenantId as static variable, is it going to be a problem?)
Can any one suggest me any solution?
Thank you,
Udeshika
if you are developing multi-tenancy application and would like to have tenant aware application context then have a look spring-tenancy. This will help you to have beans injected which are tenant aware.
if you want to multi-tenancy at hibernate layer then you can also look at multi-tenancy feature of hibernate.

Implementing DAO with Spring

I'm thinking of implementing Objectify DAO with dependency injection, such that I can maintain my code to access the same "Dao" while the implementation may change from Objectify to Hibernate-MySQL or MongoDb in the future without me worrying on changing any code in the UI or client side.
UserDao is based on the example here:
http://turbomanage.wordpress.com/2010/01/28/simplify-with-objectify/
UserObjectifyDaoImpl implements Dao<User> {
private UserDao dao = null;
public void put(User entity) {
if (dao == null) {
dao = new UserDao();
}
dao.put(entity);
}
// other put and set methods
}
Such that, I have the context.xml:
<bean id="userDao" class="com.example.server.daoimpl.UserObjectifyDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
And if I need to change the implementation, I just need to change this bean from UserObjectifyDaoImpl to something like:
UserHibernateDaoImpl or UserMongoDBDaoImpl or whatever implementation saving to whatever database.
And still have my code in the UI / Client intact, like:
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
Dao dao = (Dao) ctx.getBean("userDao");
dao.put(something);
One reason I need to do this right now, I need to develop using app engine (via objectify), however in the future I may need to change some data access objects to hibernate and some to mongodb (so its a mix).
I haven't tested this code, will this strategy work?
Yes, this will work. In fact this is one of the major reasons why DI and coding to an interface was invented. Just make sure that all DAO implementations follow the same contract (DAOs very often introduce leaky abstractions).
Also you have several other options to achieve the same goal:
Several #Service annotated classes with one marked as #Primary (if you are using autowiring)
Spring profiles and selective activation of beans
BTW if you are considering switching to a different DAO implementation, have a look at CrudRepository from Spring Data. Spring Data project provides several modules that implement this interface for MongoDB, Neo4J, JPA, etc.
For the time being it seems like several Spring Data modules do not play together nicely (see: DATAJPA-146), so if you choose to implement CrudRepository make sure this issue is fixed or you can work it around. Thanks to #iddqd for pointing that out.
You can changes context config to selected Dao implementation if you only need one implementation in application but if you need more than one implementation in your application(mixing mode), you need design Factory Layer. You trying design a layer with name Factory and with its APIs and implementations and it decide witch Dao(Hibernate, MongoDB, JP or etc) in any time must select.

Multiple JdbcTemplate instances or not?

From what I understand, both DataSource and JdbcTemplates are threadsafe, so you can configure a single instance of a JdbcTemplate and then safely inject this shared reference into multiple DAOs (or repositories). Also DataSourceshould be a Spring singleton, since it manages the connection pool.
The official Spring Documentation JdbcTemplate best practices explains the alternatives (excerpts from the manual are in italics, and my notes between square brackets:
configure a DataSource in your Spring configuration file, and then dependency-inject that shared DataSource bean into your DAO classes; the JdbcTemplate is created in the setter for the DataSource. [with XML configuration and this leads to multiple JdbcTemplate instances, since in the datasource setter there is new JdbcTemplate(dataSource)]
use component-scanning and annotation support for dependency injection. In this case you annotate the class with #Repository (which makes it a candidate for component-scanning) and annotate the DataSource setter method with #Autowired. [also this case leads to multiple JdbcTemplate instances]
If you are using Spring's JdbcDaoSupport class, and your various JDBC-backed DAO classes extend from it, then your sub-class inherits a setDataSource(..) method from the JdbcDaoSupport class. You can choose whether to inherit from this class. The JdbcDaoSupport class is provided as a convenience only. [since you've an instance of JdbcDaoSupport for each class extending it, there is an instance of JdbcTemplate too for each instance of the derived class (see source code for JdbcDaoSupport)]
However, a later note, discourages all the options just presented:
Once configured, a JdbcTemplate instance is threadsafe. You may want multiple JdbcTemplate instances if your application accesses multiple databases, which requires multiple DataSources, and subsequently multiple differently configured JdbcTemplates.
In other words, all the options just presented will result in having multiple JdbcTemplate instances (one per DAO), and just after the docs says that is not necessary when working with a single database.
What I would do is inject directly JdbcTemplate to the various DAOs needing it, so my question is, is it OK to do so? And also, do you also think that the Spring reference documentation is self-contradicting? Or is my misunderstanding?
IMO, there is no problem to inject JdbcTemplate to your (multiple) DAO(s). The template is used to "wire" your DAO to the physical resource (db connection) when you need to run db query. So if the SessionFactory and the TransactionManager are properly configured you will not run into concurrency problems - Spring manages the lifecycle of the beans you need for working with you persistence layer. The advantages of using a template are:
JDBC template manages physical resources required to interact with the DB automatically, e.g. create and release the database connections.
The Spring JDBC template converts the standard JDBC SQLExceptions into RuntimeExceptions. This allows you to react more flexible to the errors. The Spring JDBC template converts also the vendor specific error messages into better understandable error messages
so it should be spilt two situations:
We don’t change JdbcTemplate properties in DAO, we can define as below:
<bean id="tlmJDBCTemplate" class="org.springframework.jdbc.core.JdbcTemplate" <property name="dataSource" ref="plmTlmDataSource"/>
</bean>
NOTE: Most of time we don’t change the JdbcTemplate properties, because it is not necessary.
We change JdbcTemplate properties in DAO, we should be extends JdbcDaoSupport.
State:
• fetchSize: If this variable is set to a non-zero value, it will be used for setting the fetchSize property on statements used for query processing(JDBC Driver default)
• maxRows: If this variable is set to a non-zero value, it will be used for setting the maxRows property on statements used for query processing(JDBC Driver default)
• queryTimeout: If this variable is set to a non-zero value, it will be used for setting the queryTimeout property on statements used for query processing.(JDBC Driver default)
• skipResultsProcessing: If this variable is set to true then all results checking will be bypassed for any callable statement processing. This can be used to avoid a bug in some older Oracle JDBC drivers like 10.1.0.2.(false)
• skipUndeclaredResults: If this variable is set to true then all results from a stored procedure call that don't have a corresponding SqlOutParameter declaration will be bypassed. All other results processing will be take place unless the variable {#code skipResultsProcessing} is set to {#code true}(false)
• resultsMapCaseInsensitive: If this variable is set to true then execution of a CallableStatement will return the results in a Map that uses case insensitive names for the parameters if Commons Collections is available on the classpath.(false)
JdbcDaoSupport
public abstract class JdbcDaoSupport extends DaoSupport {
private JdbcTemplate jdbcTemplate;
/**
* Set the JDBC DataSource to be used by this DAO.
*/
public final void setDataSource(DataSource dataSource) {
if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
this.jdbcTemplate = createJdbcTemplate(dataSource);
initTemplateConfig();
}
}
summary: I don’t think spring give the practice in guide is the best.
Inherently spring is very subtle about best practices.
JdbcTemplate is thread-safe, notably lock-free (v4.2.4).
Meaning it should not cause performance degradation when shared between concurrent threads*.
Thus, there are no compelling reasons for more than one instance per data source.
Speculative note: this section is indeed confusing.
Probably due to historical (evolutionary) reasons.
Maybe spring had per dao policy in the past due to non thread safety or poor understading of domain at a time.
Similar to xml based configuration "disaster".
Nowadays spring renounce opinionated views and strive to be flexible instead.
Which, unfortunately, led to bad design choices being acknowleged only covertly.
* measure don't guess
After so many years, and see this question again, I think we can create "Jdbc Template" with singleton first, then inject to DAO, so it is only one instance For the Template.
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
then you can inject template to DAO or DAO extends JdbcDaoSupport.
public final void setJdbcTemplate(JdbcTemplate jdbcTemplate)
{
this.jdbcTemplate = jdbcTemplate;
initTemplateConfig();
}

How do I implement getConnection() in DataSource in Java?

I'm reading up on DataSource, here, and trying to implement it in my own little project by using a simple file as my "data source". I've created a class that is pretty simple at the moment...
public class QueueData implements DataSource { ... }
though the reason it is simple is because I haven't been able to find a resource that explains how the implemented methods should work. Everyone seems to just list the initialization of a context and a magical getConnection() call, like so.
Context ctx = new InitialContext(env1);
DataSource ds = (DataSource)ctx.lookup("jdbc/mydatasource");
Connection conn = ds.getConnection(); // Magical method!
But can one of you actually give me an example of what the code inside getConnection() should look like?
The reason no one shows samples how to implement a DataSource and "just" uses them instead is because only JDBC driver vendors (usually database makers) need to write them.
What it should do is of course return a Connection object that will also need to be an instance of of a driver-specific class. In your case, something that can accept SQL statements to read from a file.
Your code could look something like this:
public Connection getConnection(){
final String fileName = getFileNameFromMyDatabaseUrl();
return new MyFileConnection(new File(fileName));
}
Which of course is not very interesting code, either.
You can look at some open-source DataSource implementations to see what they do:
Apache Commons DBCP PoolingDataSource (a connection pool)
Apache Derby's EmbeddedDataSource (an embedded database written in Java)
Postgresql's BaseDataSource (abstract base class for the Postgresql JDBC driver)
It's not magical. You retrieve a DataSource object which was bound to the JNDI server, typically when you setup your connection pool in your application server. This setup requires you to provide all the necessary database details like connection url, authentication credentials and other options like the DataSource class for that particular database (which is present in the jdbc driver which comes with that database). This setup information is utilized to create a DataSource which knows how to hand out a connection for that given database.
Let's say that you want to write your own implementation which gives the client a NOOP connection (connection object on which all operations yield nothing). All you have to do is "register" a custom DataSource implementation with the app servers JNDI server. That implementation's getConnection() method would just return a class which implements the Connection interface and methods which do nothing.
Connection is pretty sure an interface itself, which you will need to implement as well. Then, your getConnection() will return an instance of your own class. However, be prepared for a great deal of work... (e.g., if you want to be able to get the datasource over the context, you'll need to register your implementation first.)
Why do you want to develop your own DataSource? There are very lightweight file-based and in-process database libraries available on the web (although I have to admit I don't know them too well), as for example HSQLDB (Wikipedia article), H2 (Wiki)...
If you were developing in C#, I'd also recommend to study Linq To XML, but I don't know whether the Java world has already come up with a counterpart for that...

Categories