springtestdbunit / spring-test-dbunit

Integration between the Spring testing framework and DBUnit
http://springtestdbunit.github.com/spring-test-dbunit/
Apache License 2.0
476 stars 238 forks source link

Postgrepsql's data type - jsonb can't be insert ? #165

Open nisaijie opened 4 years ago

nisaijie commented 4 years ago

how can i do ?

yuriytkach commented 4 years ago

You need to add the test configuration to your spring test where you need to configure the db connection with custom type factory for Postresql:

  @TestConfiguration
  public static class DBUnitConfig {
    @Bean
    public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(final DataSource dataSource) {
     final DatabaseConfigBean config = new DatabaseConfigBean();
    config.setDatatypeFactory(new PostgresqlDataTypeFactory() {
      @Override
      public DataType createDataType(final int sqlType, final String sqlTypeName) throws DataTypeException {
        if (sqlType == Types.OTHER && sqlTypeName.equalsIgnoreCase("json")) {
          return new JsonDataType();
        }
        return super.createDataType(sqlType, sqlTypeName);
      }
    });
    final DatabaseDataSourceConnectionFactoryBean dbConnectionFactory =
        new DatabaseDataSourceConnectionFactoryBean(dataSource);
    dbConnectionFactory.setDatabaseConfig(config);
    return dbConnectionFactory;
    }
  }

And additionally you would need the JsonDataType class, which is here:

public class JsonDataType extends AbstractDataType {
  public JsonDataType() {
    super("json", Types.OTHER, String.class, false);
  }

  public Object getSqlValue(final int column, final ResultSet resultSet) throws SQLException {
    return resultSet.getString(column);
  }

  public void setSqlValue(final Object json, final int column,
      final PreparedStatement statement) throws SQLException, TypeCastException {
    statement.setObject(column, getJson(json, statement.getConnection()));
  }

  public Object typeCast(final Object value) {
    return value != null ? value.toString() : null;
  }

  private Object getJson(final Object value, final Connection connection) throws TypeCastException {
    log.debug("getJson(value={}, connection={})", value, connection);
    try {
      @SuppressWarnings("unchecked")
      final Class<PGobject> aPGObjectClass = super.loadClass("org.postgresql.util.PGobject", connection);
      final Constructor<PGobject> ct = aPGObjectClass.getConstructor((Class<?>[]) null);
      final PGobject tempJson = ct.newInstance((Object[]) null);

      tempJson.setType("json");
      tempJson.setValue(value.toString());

      return tempJson;
    } catch (final Throwable th) {
      throw new TypeCastException(value, this, th);
    }
  }
}