I am consistently getting the following exception below when inserting values using JDBI’s @BindBean into my Mysql database within Dropwizard. The problem seems to be that JDBI is unable to find the properties in the bean. I already isolated the issue into a separate project, but can’t figure out where this is going wrong. I would be very grateful for some advice.
org.skife.jdbi.v2.exceptions.UnableToExecuteStatementException: Unable to execute, no named parameter matches "title" and no positional param for place 0 (which is 1 in the JDBC 'start at 1' scheme) has been set. [statement:"INSERT INTO `car_tbl`(`title`, `teaser`, `ext_description`, `create_date`, `teaser_image_url`, `teaser_image_color`) VALUES ( :title, :teaser, :extDescription, unix_timestamp(), :teaserImageUrl, :teaserImageColor)", located:"INSERT INTO `car_tbl`(`title`, `teaser`, `ext_description`, `create_date`, `teaser_image_url`, `teaser_image_color`) VALUES ( :title, :teaser, :extDescription, unix_timestamp(), :teaserImageUrl, :teaserImageColor)", rewritten:"/* CarDAO.createCar2 */ INSERT INTO `car_tbl`(`title`, `teaser`, `ext_description`, `create_date`, `teaser_image_url`, `teaser_image_color`) VALUES ( ?, ?, ?, unix_timestamp(), ?, ?)", arguments:{ positional:{}, named:{class:class com.javaeeeee.dwstart.db.Car}, finder:[]}] at org.skife.jdbi.v2.ColonPrefixNamedParamStatementRewriter$MyRewrittenStatement.bind(ColonPrefixNamedParamStatementRewriter.java:158) at org.skife.jdbi.v2.SQLStatement.internalExecute(SQLStatement.java:1318) at org.skife.jdbi.v2.Update.executeAndReturnGeneratedKeys(Update.java:78) at org.skife.jdbi.v2.sqlobject.UpdateHandler$1.value(UpdateHandler.java:51) at org.skife.jdbi.v2.sqlobject.UpdateHandler.invoke(UpdateHandler.java:75) at org.skife.jdbi.v2.sqlobject.SqlObject.invoke(SqlObject.java:175) at org.skife.jdbi.v2.sqlobject.SqlObject$1.intercept(SqlObject.java:75) at org.skife.jdbi.v2.sqlobject.CloseInternalDoNotUseThisClass$$EnhancerByCGLIB$$8f365cd7.createCar2(<generated>) at com.javaeeeee.dwstart.db.TestDatabase.testCreatecar2(TestDatabase.java:60)
This is my value object
public class Car { public Long carId; public String title; public String teaser; public String teaserImageUrl; public String teaserImageColor; public String extDescription; public Long createDate; }
And I have created the following DAO to make use of the @BindBean functionality as described in http://jdbi.org/sql_object_api_argument_binding/ – both methods for inserting fail.
package com.javaeeeee.dwstart.db.dao; import com.javaeeeee.dwstart.db.Car; import org.skife.jdbi.v2.sqlobject.BindBean; import org.skife.jdbi.v2.sqlobject.GetGeneratedKeys; import org.skife.jdbi.v2.sqlobject.SqlUpdate; public interface CarDAO { @GetGeneratedKeys @SqlUpdate("INSERT INTO `car_tbl`(`title`, `teaser`, `ext_description`, " + "`create_date`, `teaser_image_url`, `teaser_image_color`) " + "VALUES ( :c.title, :c.teaser, :c.extDescription, unix_timestamp(), " + ":c.teaserImageUrl, :c.teaserImageColor)") Long createCar(@BindBean("c") Car car); @GetGeneratedKeys @SqlUpdate("INSERT INTO `car_tbl`(`title`, `teaser`, `ext_description`, " + "`create_date`, `teaser_image_url`, `teaser_image_color`) " + "VALUES ( :title, :teaser, :extDescription, unix_timestamp(), " + ":teaserImageUrl, :teaserImageColor)") Long createCar2(@BindBean Car car); }
And this is my table definition.
CREATE TABLE IF NOT EXISTS `cardb`.`car_tbl` ( `car_id` INT NOT NULL AUTO_INCREMENT COMMENT '', `title` VARCHAR(255) NOT NULL COMMENT '', `teaser` VARCHAR(2048) NULL COMMENT '', `ext_description` VARCHAR(4096) NULL COMMENT '', `create_date` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '', `teaser_image_url` VARCHAR(2048) NULL COMMENT '', `teaser_image_color` VARCHAR(8) NULL COMMENT '', PRIMARY KEY (`car_id`) COMMENT '', INDEX `idx_create_date` USING BTREE (`create_date` ASC) COMMENT '') ENGINE = InnoDB;
And I am using the following JUnit integration test to recreate the error:
public class TestDatabase { private DBI dbi; private Handle handle; private CarDAO carDAO; @Before public void setUpDatabase() throws Exception { Environment environment = new Environment( "test-env", Jackson.newObjectMapper(), null, new MetricRegistry(), null ); dbi = new DBIFactory().build( environment, getDataSourceFactory(), "cardb" ); carDAO = dbi.onDemand(CarDAO.class); handle = dbi.open(); } protected DataSourceFactory getDataSourceFactory() { DataSourceFactory dataSourceFactory = new DataSourceFactory(); dataSourceFactory.setDriverClass( "com.mysql.jdbc.Driver" ); dataSourceFactory.setUrl( "jdbc:mysql://127.0.0.1:3306/cardb" ); dataSourceFactory.setUser( "root" ); dataSourceFactory.setPassword( "root" ); return dataSourceFactory; } @Test public void testCreatecar(){ Car car = new Car("Test car","Test car teaser","http://localhost:8080/","#ff0000","car test description"); Long carId = carDAO.createCar(car); assertNotNull(carId); } @Test public void testCreatecar2(){ Car car = new Car("Test car","Test car teaser","http://localhost:8080/","#ff0000","car test description"); Long carId = carDAO.createCar2(car); assertNotNull(carId); } }
I am using Java 1.8.0_05, Dropwizard 0.9.2 and MySQL 5.7.9.
Advertisement
Answer
BindBean claims to work with JavaBeans. JavaBeans require getter and setters.
Please add getters and setters to your Car class.