1

I am trying to do a simple connection using spring jdbc that returns a type Connection , at my project I am using spring jdbc with spring data, automatically configured.

At my code, I need to return this connection (with my local info).

Is it possible to do it? and in the case it is, is it possible to get the information that is being used at the moment? (I mean, dbname, password and so on..)

Thanks

EDIT------

The original dataSource bean looks like this

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="url" value="jdbc:mysql://${jdbc.host}:${jdbc.port}"/>
 </bean>

But I cannot make it with annotations, any idea?

Ive tried to do this

DriverManagerDataSource source = new org.springframework.jdbc.datasource.DriverManagerDataSource();

THE ERROR

I Keep getting that this

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required

This class extends of JdbcDaoSupport that seems like it needs of it...

Here is the JdbcDaoSupport.class

package org.springframework.jdbc.core.support;

import java.sql.Connection;
import javax.sql.DataSource;
import org.springframework.dao.support.DaoSupport;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.SQLExceptionTranslator;

public abstract class JdbcDaoSupport extends DaoSupport {
    private JdbcTemplate jdbcTemplate;

    public JdbcDaoSupport() {
    }

    public final void setDataSource(DataSource dataSource) {
        if(this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
            this.jdbcTemplate = this.createJdbcTemplate(dataSource);
            this.initTemplateConfig();
        }

    }

    protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    public final DataSource getDataSource() {
        return this.jdbcTemplate != null?this.jdbcTemplate.getDataSource():null;
    }

    public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.initTemplateConfig();
    }

    public final JdbcTemplate getJdbcTemplate() {
        return this.jdbcTemplate;
    }

    protected void initTemplateConfig() {
    }

    protected void checkDaoConfig() {
        if(this.jdbcTemplate == null) {
            throw new IllegalArgumentException("\'dataSource\' or \'jdbcTemplate\' is required");
        }
    }

    protected final SQLExceptionTranslator getExceptionTranslator() {
        return this.getJdbcTemplate().getExceptionTranslator();
    }

    protected final Connection getConnection() throws CannotGetJdbcConnectionException {
        return DataSourceUtils.getConnection(this.getDataSource());
    }

    protected final void releaseConnection(Connection con) {
        DataSourceUtils.releaseConnection(con, this.getDataSource());
    }
}

Ive declared this class as @bean and do this

public DriverManagerDataSource provideSource() {
    DriverManagerDataSource dataSource = new org.springframework.jdbc.datasource.DriverManagerDataSource();
    //this.dataSource = dataSource;
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUsername("user");
    dataSource.setPassword("pass");
    dataSource.setUrl("jdbc:mysql://localhost:3306/db");
    return dataSource;
}


@Bean
MyClientDao myClientDao(){
    MyClientDao myClientDao = new MyClientDao();
    myClientDao().setDatabaseName("db");
    myClientDao().setDataSource(provideSource());
    return myClientDao();
}

Any idea how to do it?

jpganz18
  • 5,508
  • 17
  • 66
  • 115
  • May I ask why you'd need to do that? The [documentation](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html) seems to indicate that it's Spring's job to handle the connections... – Morfic Oct 02 '15 at 15:51
  • I found out some code (I cannot change) that is requiring this to make a lock, I thought it could go and check the pool of connections but seems like it needs it to be sent as parameter of a method call – jpganz18 Oct 02 '15 at 15:52
  • 1
    Hmm, I can't quite fully figure out your context, but the answer to [this question](http://stackoverflow.com/questions/8428235/how-to-get-current-connection-object-in-spring-jdbc) (which is fairly similar to yours, duplicate?!) suggests you could use [DataSourceUtils](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/datasource/DataSourceUtils.html) – Morfic Oct 02 '15 at 15:56
  • Thanks @Morfic, Ive updated my question, could you please take a look? Ive tried with the other posts responses but no result. – jpganz18 Oct 02 '15 at 16:34
  • 1
    Not sure what you mean by `I cannot make it with annotations` but you said you're working with spring, so you should not try to instantiate the data source yourself. Instead you can simply define an autowired field in your bean: `@Autowired private DataSource dataSource;`. – Morfic Oct 02 '15 at 16:57
  • Hello, thanks for the tip @Morfic, Ive updated my ticket, could you please take a look again? – jpganz18 Oct 02 '15 at 17:51
  • The class which declares the `provideSource()` & `myClientDao()` methods should be annotated with `@Configuration` instead of `@Bean`. Docs [here](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-java) – Morfic Oct 02 '15 at 18:30

2 Answers2

3

The exception indicates that the JdbcTemplate is null. (code extract from the JdbcDaoSupport.class)

protected void checkDaoConfig() {
    if(this.jdbcTemplate == null) {
        throw new IllegalArgumentException("\'dataSource\' or \'jdbcTemplate\' is required");
    }
}

You need to wire the DAO (which is extending the JdbcDaoSupport) with the dataSource (bean)

If you create the following dao class:

public class CustomDaoImpl extends JdbcDaoSupport implements CustomDao {
...<implementation>
}

Your configuration would be:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="url" value="jdbc:mysql://${jdbc.host}:${jdbc.port}"/>
 </bean>

<bean id="myClientDao" class="package.MyClientDao">
    <property name="dataSource" ref="dataSource" />
</bean>

This way the JdbcTemplate will be initialized correctly.

With annotations, this will look like the following:

@Configuration
public class ConfigBean {
    @Bean
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource dataSource = new org.springframework.jdbc.datasource.DriverManagerDataSource();
        //this.dataSource = dataSource;
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("user");
        dataSource.setPassword("pass");
        dataSource.setUrl("jdbc:mysql://localhost:3306/db");
        return dataSource;
    }

    @Bean
    public MyClientDao myClientDao(){
        MyClientDao myClientDao = new MyClientDao();
        myClientDao.setDataSource(dataSource());
        return myClientDao;
    }
}

Do not forget to add the @Bean annotation to the dataSource.

Sidenotes:

  • spring uses 'dataSource' as the 'default datasource' name
  • When working with dao/repository, the dataSource is mandatory, so spring advises you to add the datasource as a parameter to the constructor of your dao
deketim
  • 859
  • 6
  • 6
  • Hi, yeah, that is the way the conf bean should look like, but I dont have a xml, I just can use a class file and set it as annotation, u have an idea how to do it with annotations? – jpganz18 Oct 02 '15 at 20:13
  • 1
    I have added the corresponding Java configuration in the answer. Hope this helps. – deketim Oct 02 '15 at 20:53
  • I had written it on that exact way but still didnt work... at the DAO class I have the @Service annotation,should I remove it? or include other one? – jpganz18 Oct 02 '15 at 22:51
  • Spring typically uses @Repositoy to indicate a dao class. – deketim Oct 03 '15 at 06:43
0

To Mae JDBC connection ( Using Spring Boot ) You need to first:

  1. Define DB properties in .properties file.
  2. Then Use JDBCTemplate Class for DB connection.

A Step by step implementation is given here.

Mohit kumar
  • 248
  • 3
  • 12