DBunit - 无法进行类型转换< 1997/02/14>到TimeStamp

时间:2016-06-28 10:02:43

标签: java hibernate hsqldb dbunit

我正在使用DB tutorial进行与DBUnit(2.49)+ Hibernate(4.1.3)的集成测试。

  • 生产数据库:Oracle 10
  • 测试数据库:Hsqldb 2.3.3

上下文

我的数据包含当前日期格式:yyyy/MM/dd。但是,根据DBUnit faq,DBUnit仅支持此格式yyyy-mm-dd hh:mm:ss.fffffffff,因此我必须为TimeStamp创建一种新格式。

我是如何尝试修复的

  • 我根据此tutorial创建了CustomTimeStampDataType。我改变了这一部分:

    String formats[] = {"yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm a", "yyyy-MM-dd HH:mm:ss.fffffffff"};
    

进入这一个:

    String formats[] = {"yyyy/MM/dd"};
  • 我按照相同的教程创建了CustomeDataTypeFactory。我只扩展Oracle10DataTypeFactory而不是DefaultDatatTypeFactory
  • HibernateDBUnitTestCase中,我使用以下内容覆盖setDatabaseConfig()

    @Override
    protected void setUpDatabaseConfig(DatabaseConfig config){
        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new CustomDataTypeFactory());
      }
    

但是我遇到了新的错误

我进行了单元测试并得到了这个错误。

org.dbunit.dataset.datatype.TypeCastException: Unable to typecast value <1997/02/14> of type <java.lang.String> to TIMESTAMP
    at org.dbunit.dataset.datatype.TimestampDataType.typeCast(TimestampDataType.java:120)
    at org.dbunit.dataset.datatype.TimestampDataType.setSqlValue(TimestampDataType.java:176)
    at org.dbunit.database.statement.SimplePreparedStatement.addValue(SimplePreparedStatement.java:73)
    at org.dbunit.operation.RefreshOperation$RowOperation.execute(RefreshOperation.java:189)
    at org.dbunit.operation.RefreshOperation.execute(RefreshOperation.java:113)
    at org.dbunit.AbstractDatabaseTester.executeOperation(AbstractDatabaseTester.java:190)
    at org.dbunit.AbstractDatabaseTester.onSetup(AbstractDatabaseTester.java:103)
    at org.dbunit.DatabaseTestCase.setUp(DatabaseTestCase.java:156)
    at test.HibernateDbUnitTestCase.setUp(HibernateDbUnitTestCase.java:85)
    at test.PlayerTest.setUp(PlayerTest.java:117)

Caused by: java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
    at java.sql.Timestamp.valueOf(Unknown Source)
    at org.dbunit.dataset.datatype.TimestampDataType.typeCast(TimestampDataType.java:116)
    ... 20 more

这很奇怪,似乎我的CustomTimeStamp没有被调用,所以我使用默认格式更改了数据集中的日期:1997-02-14 00:00:00.0,并运行了再次进行单元测试然后我得到了:

org.dbunit.dataset.datatype.TypeCastException: Unable to typecast value <1997-02-14 00:00:00.0> of type <java.lang.String> to TIMESTAMP
    at test.CustomTimestampDataType.typeCast(CustomTimestampDataType.java:69)
    at test.CustomTimestampDataType.setSqlValue(CustomTimestampDataType.java:84)
    at org.dbunit.database.statement.SimplePreparedStatement.addValue(SimplePreparedStatement.java:73)
    at org.dbunit.operation.RefreshOperation$RowOperation.execute(RefreshOperation.java:189)
    at org.dbunit.operation.RefreshOperation.execute(RefreshOperation.java:113)
    at org.dbunit.AbstractDatabaseTester.executeOperation(AbstractDatabaseTester.java:190)
    at org.dbunit.AbstractDatabaseTester.onSetup(AbstractDatabaseTester.java:103)
    at org.dbunit.DatabaseTestCase.setUp(DatabaseTestCase.java:156)
    at test.HibernateDbUnitTestCase.setUp(HibernateDbUnitTestCase.java:85)
    at test.PlayerTest.setUp(PlayerTest.java:117)

这意味着 CustomTimeStamp实际上被称为。似乎,问题来自DatabaseTestCase.setUp,它以某种方式调用了错误的TimeStampDataType。

我该如何解决这个问题?

  • 我的第一个选择是使用正则表达式将数据集中的每个yyyy/MM/dd替换为yyyy-mm-dd。这工作正常,直到我必须测试一个基于请求选择日期的方法(因此格式为yyyy-mm-dd)并将其与当前日期进行比较。 (所以格式为yyyy / mm / dd)。 Hsqldb无法比较两种格式不同的日期。

  • 我的第二个选择是反编译dbunit.jar,根据教程重写TimeStampDataType。我不熟悉字节码编写,所以在进入未知的水域之前,我想知道你是否有另一种解决方案。

提前谢谢

1 个答案:

答案 0 :(得分:1)

修正了它!

所以我最终使用了我的第二个选项。 这是需要它的人的详细路径。

  • 下载dbUnit.2.2.source.jar
  • 解压缩jar
  • 转到Eclipse,File > New > Java Project
  • 取消选中"Use default location"
  • 在位置:指定从jar
  • 创建的新文件夹的路径
  • 点击Finish
  • 修改TimestampDataType.java(如果需要)

    • 而不是ts = java.sql.Timestamp.valueOf(stringValue);使用下面的代码

          String formats[] =
           {"dd/MM/yyyy HH:mm:ss.SS"}; //and more depending on your need
           Timestamp ts = null;
           for (int i = 0; i < formats.length; i++) 
           {
           SimpleDateFormat sdf = new SimpleDateFormat(formats[i]);
           try {
               java.util.Date date = sdf.parse(stringValue);
               ts = new Timestamp(date.getTime());
               return ts;
           }
           catch( ParseException e) {
          }
      
  • 修改DateDataType.java(如果需要)

    • 使用下面的代码

      代替return java.sql.Date.valueOf(stringValue);
      String formats[] =
           {"dd/MM/yyyy"};  //and more depending on your need
           for (int i = 0; i < formats.length; i++) 
           {
           SimpleDateFormat sdf = new SimpleDateFormat(formats[i]);
      
           try {
      
           java.util.Date date = sdf.parse(stringValue);
           java.sql.Date datesql = new java.sql.Date(date.getTime());
           return datesql;
           }
           catch( ParseException e) {
           }
           }
      
  • 右键点击您的项目,然后点击Export
  • 选择JAR file,然后选择Next
  • 填写导出目的地,然后填写Finish
  • 您只需将此新jar添加到库中即可使用。