DbUnit 和 JSON 列类型支持
DbUnit and JSON column type support
我想知道使 DbUnit 与 MySQL 的 JSON(B) 类型列一起工作的最佳方法是什么?我们确实到处都有这样的列,每当我尝试通过 @DatabaseSetup
从 XML 文件提供测试数据时,我都会收到 NoSuchColumnException,这会阻止我与实体或 repos 进行任何合理的集成测试处理 JSON:
org.dbunit.dataset.NoSuchColumnException: assistant_event.AEV_CONTEXT - (Non-uppercase input column: aev_context) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
我知道这是因为我的 AEV_CONTEXT
专栏没有被识别,因为它是一个 JSON 专栏:
@Type(type = "json")
@Column(name = "aev_context", columnDefinition = "json")
private Context context;
但是,我在尝试解决它时遇到了困难。而且,更奇怪的是,我在这里的任何地方都找不到这样的解决方法!事实上,我不知道那是更多的 Hibernate 还是 DbUnit。
到目前为止真的只有我有这个问题吗?任何建议将不胜感激!
哦,如果您想知道,这就是我如何获得 JSON 对 Hibernate 的支持:
https://vladmihalcea.com/how-to-map-json-objects-using-generic-hibernate-types/
一个可能的解决方案是定义您自己的 DataTypeFactory 并使用它。我这样做是为了支持 PostgreSQL JSONB 数据类型,可以为 MySQL.
做类似的事情
class NewPostgresqlDataTypeFactory : PostgresqlDataTypeFactory() {
override fun createDataType(sqlType: Int, sqlTypeName: String?): DataType {
return when (sqlTypeName) {
"jsonb" -> return JsonbDataType()
else -> super.createDataType(sqlType, sqlTypeName)
}
}
class JsonbDataType : AbstractDataType("jsonb", Types.OTHER, String::class.java, false) {
override fun typeCast(obj: Any?): Any {
return obj.toString()
}
override fun getSqlValue(column: Int, resultSet: ResultSet): Any {
return resultSet.getString(column)
}
override fun setSqlValue(value: Any?, column: Int, statement: PreparedStatement) {
val jsonObj = PGobject()
jsonObj.type = "json"
jsonObj.value = value?.toString()
statement.setObject(column, jsonObj)
}
}
}
如果有人需要它,这是 PostgreSQL JSONB 数据类型的 的 Java 版本:
import org.dbunit.dataset.datatype.AbstractDataType;
import org.dbunit.dataset.datatype.DataType;
import org.dbunit.dataset.datatype.DataTypeException;
import org.dbunit.dataset.datatype.TypeCastException;
import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory;
import org.postgresql.util.PGobject;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class NewPostgresqlDataTypeFactory extends PostgresqlDataTypeFactory {
@Override
public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException {
if (sqlTypeName.equals("jsonb")) {
return new JsonbDataType();
} else {
return super.createDataType(sqlType, sqlTypeName);
}
}
public static class JsonbDataType extends AbstractDataType {
public JsonbDataType() {
super("jsonb", Types.OTHER, String.class, false);
}
@Override
public Object typeCast(Object obj) throws TypeCastException {
return obj.toString();
}
@Override
public Object getSqlValue(int column, ResultSet resultSet) throws SQLException, TypeCastException {
return resultSet.getString(column);
}
@Override
public void setSqlValue(Object value,
int column,
PreparedStatement statement) throws SQLException, TypeCastException {
final PGobject jsonObj = new PGobject();
jsonObj.setType("json");
jsonObj.setValue(value == null ? null : value.toString());
statement.setObject(column, jsonObj);
}
}
}
我想知道使 DbUnit 与 MySQL 的 JSON(B) 类型列一起工作的最佳方法是什么?我们确实到处都有这样的列,每当我尝试通过 @DatabaseSetup
从 XML 文件提供测试数据时,我都会收到 NoSuchColumnException,这会阻止我与实体或 repos 进行任何合理的集成测试处理 JSON:
org.dbunit.dataset.NoSuchColumnException: assistant_event.AEV_CONTEXT - (Non-uppercase input column: aev_context) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
我知道这是因为我的 AEV_CONTEXT
专栏没有被识别,因为它是一个 JSON 专栏:
@Type(type = "json")
@Column(name = "aev_context", columnDefinition = "json")
private Context context;
但是,我在尝试解决它时遇到了困难。而且,更奇怪的是,我在这里的任何地方都找不到这样的解决方法!事实上,我不知道那是更多的 Hibernate 还是 DbUnit。
到目前为止真的只有我有这个问题吗?任何建议将不胜感激!
哦,如果您想知道,这就是我如何获得 JSON 对 Hibernate 的支持:
https://vladmihalcea.com/how-to-map-json-objects-using-generic-hibernate-types/
一个可能的解决方案是定义您自己的 DataTypeFactory 并使用它。我这样做是为了支持 PostgreSQL JSONB 数据类型,可以为 MySQL.
做类似的事情class NewPostgresqlDataTypeFactory : PostgresqlDataTypeFactory() {
override fun createDataType(sqlType: Int, sqlTypeName: String?): DataType {
return when (sqlTypeName) {
"jsonb" -> return JsonbDataType()
else -> super.createDataType(sqlType, sqlTypeName)
}
}
class JsonbDataType : AbstractDataType("jsonb", Types.OTHER, String::class.java, false) {
override fun typeCast(obj: Any?): Any {
return obj.toString()
}
override fun getSqlValue(column: Int, resultSet: ResultSet): Any {
return resultSet.getString(column)
}
override fun setSqlValue(value: Any?, column: Int, statement: PreparedStatement) {
val jsonObj = PGobject()
jsonObj.type = "json"
jsonObj.value = value?.toString()
statement.setObject(column, jsonObj)
}
}
}
如果有人需要它,这是 PostgreSQL JSONB 数据类型的
import org.dbunit.dataset.datatype.AbstractDataType;
import org.dbunit.dataset.datatype.DataType;
import org.dbunit.dataset.datatype.DataTypeException;
import org.dbunit.dataset.datatype.TypeCastException;
import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory;
import org.postgresql.util.PGobject;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class NewPostgresqlDataTypeFactory extends PostgresqlDataTypeFactory {
@Override
public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException {
if (sqlTypeName.equals("jsonb")) {
return new JsonbDataType();
} else {
return super.createDataType(sqlType, sqlTypeName);
}
}
public static class JsonbDataType extends AbstractDataType {
public JsonbDataType() {
super("jsonb", Types.OTHER, String.class, false);
}
@Override
public Object typeCast(Object obj) throws TypeCastException {
return obj.toString();
}
@Override
public Object getSqlValue(int column, ResultSet resultSet) throws SQLException, TypeCastException {
return resultSet.getString(column);
}
@Override
public void setSqlValue(Object value,
int column,
PreparedStatement statement) throws SQLException, TypeCastException {
final PGobject jsonObj = new PGobject();
jsonObj.setType("json");
jsonObj.setValue(value == null ? null : value.toString());
statement.setObject(column, jsonObj);
}
}
}