org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter

user4821194 picture user4821194 · Sep 20, 2016 · Viewed 18.1k times · Source

I'm working on Spring JDBC example using the BeanPropertySqlParameterSource and SqlParameterSource. When I run my code I see the following error is comming. After spending couple of hours I dont find its solution. Please guide whats wrong here.

org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter 'employeeId': Invalid property 'employeeId' of bean class [com.spring.jdbc.model.Order]: Bean property 'employeeId' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:342)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:348)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:211)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:226)
    at com.spring.jdbc.dao.OrderDAOImpl.countOfOrders(OrderDAOImpl.java:51)
    at com.spring.batch.OrderTest.testCountByEmployeeIdAndShipperId(OrderTest.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

OrderDAOImpl.java

    @Override
        public Long countOfOrders(Order order) {
            String sql = "SELECT count(*) FROM orders WHERE EmployeeID = :employeeId AND ShipperID = :shipperId ";

            SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(order);

           Long count = namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Long.class);
            return count;
        }

OrderTest.java

@Test
    public void testCountByEmployeeIdAndShipperId() {
        Order order = new Order();
        order.setEmployeeID(3);
        order.setShipperID(2);

        Long countEmployee = orderDAO.countOfOrders(order);
        System.out.println("Count : "+countEmployee);
    }

OrderDAO.java

public interface OrderDAO {
    Long countByEmployeeId(Long employeeId);

    Long countByShipperId(Long shipperId);

    Long countOfOrders(Order order);
}

Order.java

public class Order {
    private int orderId;
    private int customerID;
    private int employeeID;
    private Date orderDate;
    private int shipperID;

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    public int getCustomerID() {
        return customerID;
    }

    public void setCustomerID(int customerID) {
        this.customerID = customerID;
    }

    public int getEmployeeID() {
        return employeeID;
    }

    public void setEmployeeID(int employeeID) {
        this.employeeID = employeeID;
    }

    public Date getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }

    public int getShipperID() {
        return shipperID;
    }

    public void setShipperID(int shipperID) {
        this.shipperID = shipperID;
    }
}

Customer.java

public class Customer {
    private int customerID;
    private String customerName;
    private String contactName;
    private String address;
    private String city;
    private String postalCode;
    private String country;

    public int getCustomerID() {
        return customerID;
    }

    public void setCustomerID(int customerID) {
        this.customerID = customerID;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}

Beans.xml

<?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"
    xsi:schemaLocation="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:property-placeholder location="classpath:database.properties" />

    <!-- Initialization for data source -->
    <bean id="dataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver.class.name}" />
        <property name="url" value="${jdbc.driver.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>


    <bean id="orderTemplate" class="com.spring.jdbc.dao.OrderDAOImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="customerTemplate" class="com.spring.jdbc.dao.CustomerDAOImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

Answer

Pra_A picture Pra_A · Sep 20, 2016

Oh I see the issue. The issue is in query, variable name is not matching at all. Use below query. Done !!

 String sql = "SELECT count(*) FROM orders WHERE EmployeeID = :employeeID AND
 ShipperID = :shipperID ";

You should use shipperID and employeeID and not shipperId and employeeId