代码之家  ›  专栏  ›  技术社区  ›  keyboardsamurai

JDBI的@BindBean在INSERT期间未在bean类中找到命名参数

  •  6
  • keyboardsamurai  · 技术社区  · 8 年前

    在Dropwizard中使用JDBI的@BindBean将值插入Mysql数据库时,我始终会遇到以下异常。问题似乎是JDBI无法在bean中找到属性。我已经把这个问题孤立在一个单独的项目中,但我不知道这出了什么问题。我非常感谢你的建议。

    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)
    

    这是我的价值对象

    public class Car {
        public Long carId;
        public String title;
        public String teaser;
        public String teaserImageUrl;
        public String teaserImageColor;
        public String extDescription;
        public Long createDate;
    }
    

    我创建了以下DAO,以使用@BindBean功能,如中所述 http://jdbi.org/sql_object_api_argument_binding/ -两种插入方法都失败。

    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);
    }
    

    这是我的表格定义。

    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;
    

    我正在使用以下JUnit集成测试来重新创建错误:

    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);
        }
    }
    

    我使用的是Java 1.8.0_05、Dropwizard 0.9.2和MySQL 5.7.9。

    2 回复  |  直到 8 年前
        1
  •  16
  •   ahus1    8 年前

    BindBean声称可以使用JavaBeans。JavaBean需要getter和setter。

    请将getter和setter添加到您的Car类中。

        2
  •  1
  •   Juliano Suman Curti    3 年前

    我有一个问题:

        UnableToCreateStatementException, message: Missing named parameter 'isFavorite'.
    

    那是因为我的目标只是:

        public boolean isFavorite() {
                return this.isFavorite
        }
    

    然后我把它改成了 getIsFavorite() 它起了作用。 注意,这个getter必须是 public .