Spring 引导 MongoDB 持久性映射异常:无法将 Java.util.ArrayList 转换为 class java.lang.Object 的实例

Spring Boot MongoDB Persistance MappingException: Cannot convert Java.util.ArrayList into an instance of class java.lang.Object

tl;dr

问题

依赖项

所以这是我的问题 我正在尝试在 Spring 引导应用程序中为 MongoDB 添加持久性,在这种情况下我使用的是 tables,问题恰好出现TableRaw bean(Table 的精简版只是为了持久化)。

Document(collection = "rule_tables")
public class TableRaw {

    @Id
    private String _id;
    private String key;
    private String name;
    private String returns;
    private ArrayList<AxisRaw> axis;

    private ArrayList<Object> values = new ArrayList<>();
}

其他一切只是默认构造函数(没有 _id)和 getsetter。

因此,除了值 ArrayList 之外,一切正常。如果它只是一个简单的 ArrayList 和数字等等,它就可以正常工作但是在我的情况下我想要像我插入到数据库中的东西(每次运行时都会这样做用于测试目的和插入的值使用 MongoRepository,它工作正常)

{
  "_id":"5ac20c8b8ee6e6360c8947be",
  "key":"1",
  "name":"Table 1",
  "returns":"Number",
  "axis":[
     {
       "name":"potato",
       "values":[
          {
             "_id":"BottomEdge","value":0
          },{
             "_id":"Range",
              "value":[1,2]
          },{
             "_id":"TopEdge",
             "value":3
          }
        ]
      }
   ],
  "values":[
      [1,2,3],
      [1,2,3],
      [1,2,3]
  ],
  "_class":"pt.i2s.gm.gm.rulehandler.tables.model.TableRaw"
}

(对于代码中的使用,轴长度和轴数很重要,但在这种情况下完全不相关。)

无论如何,如前所述,它可以很好地插入 MongoDB,但在尝试获取值时出现以下错误。

 org.springframework.data.mapping.MappingException: Cannot convert [1, 2, 3] of type class java.util.ArrayList into an instance of class java.lang.Object! Implement a custom Converter<class java.util.ArrayList, class java.lang.Object> and register it with the CustomConversions. Parent object was: [empty]

首先 首先我不太清楚父对象是什么:[empty] 表示.

第二个 我试着创建一个 AttributeConverter 这样:

@Component
@Converter(autoApply = true)
public class ArrayList2ObjectConverter implements 
AttributeConverter<ArrayList<Object>,Object> {

    @Override
    public Object convertToDatabaseColumn(ArrayList<Object> attribute) {
        return attribute;
    }

    @SuppressWarnings("unchecked") //If you don't like it suppress it
    @Override
    public ArrayList<Object> convertToEntityAttribute(Object dbData) {
        System.out.println("Converting...");
        return (ArrayList<Object>)dbData;
    }

}

并在 values 属性上方添加 @Convert(converter = ArrayList2ObjectConverter.class)。然而,这甚至没有被调用。

出于某种原因,我找不到这个问题的任何答案,可能是因为我的编码不好,做了一些愚蠢的事情,所以没有人会这样做,因为它不起作用。

那我该怎么做呢?感谢您的阅读。

有关轴和值金额的更新

如果我从一开始就知道 table 添加了哪些类型的值,那么 thomi 会建议一些有用的东西。我很欣赏你的回答,但是应该对此做出一些澄清。

我不想使用的可能解决方案

我可以简单地创建一个包含字符串的对象和一个可能工作正常的 ArrayList,但是我想避免这种解决方案,因为我不想向数据库添加不相关的信息。

采用的解决方案

应@user_531的要求,我将添加此问题的解决方案。

因为这不起作用,我改变了使用名为 ValueList 的新对象的方法,它只是单个对象

的包装器 class
private ArrayList<ValueList> values;

值列表Class

public class ValueList {
  public Object value;
}

这允许我将我想要的任何类型的对象添加到列表中,但这确实导致 tables 看起来像这样:

{
  "key":1,
  ...... (Same as above)
  "values": [
       {
         "value": [
            {
              "value":1
            },
            {
              "value":2
            }
         ]
       },
       {
         "value": [
            {
              "value":3
            },
            {
              "value":4
            }
          ]
       }
    ]
}

这看起来很可笑,但它不再失败,并且允许我根据 "isValueList()" 的结果调用 "getValue()" 方法或 "getValueList()" 方法来相对一致地读取值.

我认为你不应该将某些东西映射到一个对象。在你的数据库中,你肯定会知道你的数组中会有什么数据类型,在你的情况下,尝试替换为:

@Document(collection = "rule_tables")
public class TableRaw {

  @Id
  private String _id;
  private String key;
  private String name;
  private String returns;
  private ArrayList<AxisRaw> axis;

  private List<List<Integer>> values; // no initialization.
}

这应该可以很好地映射您的结构。