Spring Boot MongoDB Persistance MappingException:无法将Java.util.ArrayList转换为java.lang.Object类的实例

时间:2018-04-02 11:47:11

标签: java mongodb spring-boot arraylist spring-data-mongodb

TL;博士

  • 尝试添加一个ArrayList,其中Object可以是一个ArrayList to Persistance。
  • 尝试添加AttributeConverter>失败
  • Plz帮助
  • 我不知道我在做什么。
  • 我有多愚蠢?

问题

依赖关系

  • spring-boot-starter-data-jpa 2.0.0
  • spring-boot-starter-data-mongodb 2.0.0
  • eclipselink 2.7.1< - 可能不需要这个,不确定。

所以这是我的问题我试图在MongoDB的Spring启动应用程序中添加持久性,在这种情况下我正在使用表,问题恰好出现在 TableRaw bean(条带化版本)表只是为了坚持)。

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)和getsetters。

所以一切正常,但值 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]

首先 首先我不知道父对象是什么:[空] 表示。

第二次 我尝试创建 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)。然而,这甚至没有被召唤。

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

那我该怎么做?谢谢你的阅读。

有关轴和值金额的更新

如果我知道从表中添加了什么类型的值,那么thomi就可以使用一些可行的东西。我赞成回答,但是应该对此作出一些澄清。

  • 我不知道有多少Axis,因此我将拥有嵌套数组,它可能是1,它可能是30。
  • 我不知道对象的类类型是什么,它可能是数字,字符串,布尔值,日期等等。选项有限但仍然很广泛。

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

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

采用解决方案

根据@ user_531的请求,我将为此问题添加解决方案。

由于这不起作用,我改变了我的方法,使用了一个名为ValueList的新对象,它只是一个Object的包装类

private ArrayList<ValueList> values;

ValueList Class

public class ValueList {
  public Object value;
}

这允许我将任何类型的对象添加到列表中,但这会产生如下表格:

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

哪个看起来很隐蔽,但它不再失败,并允许我通过调用&#34; getValue()&#34;相对一致地读取值。方法或&#34; getValueList()&#34;方法根据&#34; isValueList()&#34;。

的结果

1 个答案:

答案 0 :(得分:-1)

我认为你不应该把东西映射到一个对象。在您的数据库中,您肯定会知道您的数组中将包含哪种数据类型,在您的情况下,请尝试并替换为:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys, psycopg2

...

    conn = psycopg2.connect("dbname=dbname user=user password=password")
    cur = conn.cursor()

    sql = "\copy (SELECT * FROM table WHERE month=6) TO '/mnt/results/month/table.csv' WITH CSV DELIMITER ';';"
    cur.execute(sql)
    cur.close()

...

这应该很好地映射你的结构。