1
votes

I am trying to make DAO with JdbcTemplate. But it seems that Spring injection not going well. I am injecting DataSource with JNDI from Tomcat.

Also I wrote settings in Tomcats server.xml, ResourceLink in /META-INF, resource-ref in web.xml, tried to add context-listener in web.xml, it also doesn`t help (actually, should I add listener, if I am not accessing DataSource from servlets, but only from DAO?).

What am I missing, why Spring not injecting it?

dao-context.xml

 <context:component-scan base-package="somepackage"/>
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/phonebook" expected-type="javax.sql.DataSource"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

web.xml

 <resource-ref>
    <description>DatasourceJNDI</description>
    <res-ref-name>jdbc/phonebook</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

META-INF/context.xml

<Context>
<ResourceLink name="jdbc/phonebook" global="jdbc/global_phonebook" type="javax.sql.DataSource"/>

server.xml in Tomcat

<Resource name="jdbc/global_phonebook" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/phonebook" username="root" password="1234" maxActive="10" maxIdle="5" maxWait="-1" defaultAutoCommit="false" defaultTransactionIsolation="READ_COMMITTED"/>

tomcat localhost log http://shorttext.com/700e4579 tomcat catalina log http://shorttext.com/700f24cb

1
I assume, you have no exception in log, that dataSource cannot be found, so I'd say the problem is in your injection? How are you creating DAO, share also configuration, please.Betlista
I have NullPointerException at line: 168. This line has jdbcTemplate.getDataSource() method. Printed dataSource variable, and it says that it is "null", as jdbcTemplate too. So I assume JNDI not injected. DAOs injected with Autowired annotation, and defined with Repository annotation. Scanned in context.xml with <context:component-scan/>. DAOs injection works. Updated question with context configurations.Mikhail
Can you post the stacktrace?Wins
sure. StackOverflow do not allow paste, added link to txt in questionMikhail

1 Answers

0
votes

Only difference I can see comparing with my working example is, that I hace in Tomcat's context.xml this:

<Resource name="jdbc/MySQL"
            auth="Container"
            type="javax.sql.DataSource"
            username="root"
            password=""
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/so"
            maxActive="8"
            maxIdle="4"/>

I tested this with Tomcat 7.0.47 and I followed this documentation - https://tomcat.apache.org/tomcat-7.0-doc/jndi-resources-howto.html

edit:

I read your comment again and if

jdbcTemplate.getDataSource()

throwing NPE, then jdbcTemplate has to be null. Can you share your DAO code?


Hi Misha, sorry for a late answer.

I created very simple controller to test:

@Controller
public class ExecuteController {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @ResponseBody
    @RequestMapping(path="execute")
    public String execute() {
        return new Date().toString() + ": executed " + (jdbcTemplate == null);
    }

}

and when I executed it, I got

Wed Jan 06 09:22:59 CET 2016: executed false

and false means it is not null.

I have empty root context and servlet context is:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="test" />

    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/MySQL" expected-type="javax.sql.DataSource"/>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>

</beans>

so, the combination of component-scan, @Controller and @Autowired does the trick.

I real life I wouldn't access JdbcTemplate from Controller, but via service and dao layers, but that would be too complicated for now...