Поддержка типов столбцов DbUnit и JSON - PullRequest
0 голосов
/ 17 октября 2018

Мне интересно, каков наилучший способ заставить DbUnit работать со столбцами типа MySQL JSON (B)?У нас есть такие столбцы здесь и там, и всякий раз, когда я пытаюсь передать тестовые данные из файла XML через @DatabaseSetup, я получаю исключение NoSuchColumnException, которое не позволяет мне создавать любые разумные интеграционные тесты с сущностями или репозиториями, которые работают с 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/

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Если кому-то это нужно, это Java-версия решения @ Алекси для типа данных 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);
        }
    }
}
0 голосов
/ 30 ноября 2018

Одним из возможных решений является определение собственного 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)
        }
    }
}
...