如何映射Map <string,list <integer =“”>&gt;从JSON到JPA?

时间:2018-03-31 22:50:05

标签: java json hibernate jpa

我尝试了很多不同的解决方案,但没有任何工作。这就是我现在所拥有的:

我的数据对于玩家来说会是这样的:

/core/plugins/plugin1/css/style.css

我正在尝试绘制能力。

这是我的代码:

/var/www/example.com/src/plugins/plugin1/client/css/style.css

然后:

{
"id": 1,
"name": "Stalker",
"type": "dark",
"faction": 3,
"weaponAbilities": {
"normal": [
  5,
  1,
  0
],
"dark": [
  4,
  2,
  8
]}
}

我得到的错误:

@Data
@Entity
@Table(name = "player")
@EntityListeners(AuditingEntityListener.class)
public class Player {  

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @OneToMany
    Map<String, Abilities> weaponAbilities;

}

2 个答案:

答案 0 :(得分:1)

首先错误是JSON,而不是JPA,所以如果你的意思是要解决这个问题,那就重述一下。

我在这里回答如何在JPA中映射类以便能够持久保存该类型的字段。由于您尚未定义如何在数据库中保留该信息,因此您可以在不需要包含List<Integer>的人工实体的情况下执行此操作,如下所示

@Entity
public class Player 
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @CollectionTable
    @ElementCollection
    @Convert(attributeName="value",converter=ListIntegerStringConverter.class)
    Map<String, List<Integer>> weaponAbilities;
}

然后,这将把Map字段存储到一个单独的表中,其中键存储在VARCHAR列中,值存储在VARCHAR列中。如果需要采用常规JPA方式,则可以控制这些列的大小。 List<Integer>可以以逗号分隔或JSON或其他任何方式存储到此值列中。例如,使用逗号分隔

@Converter(autoApply=true)
public class ListIntegerStringConverter implements AttributeConverter<List<Integer>, String>
{
    public String convertToDatabaseColumn(List<Integer> attribute)
    {
        if (attribute == null)
        {
            return null;
        }
        StringBuilder str = new StringBuilder();
        for (Integer val : attribute)
        {
            if (str.length() > 0)
            {
                str.append(",");
            }
            str.append(val);
        }
        return str.toString();
    }

    public List<Integer> convertToEntityAttribute(String dbData)
    {
        if (dbData == null)
        {
            return null;
        }

        List<Integer> list = new ArrayList<>();
        StringTokenizer tokeniser = new StringTokenizer(dbData, ",");
        while (tokeniser.hasMoreTokens())
        {
            list.add(Integer.valueOf(tokeniser.nextToken()));
        }

        return list;
    }
}

但这一切都取决于你对这个List的要求是什么,你是否可能有大量的元素,是否要查询,等等,这可能会影响你是否愿意使用中间实体,或将其放入单个列中(如此处所示)。

答案 1 :(得分:0)

尝试使用:

private Map<String, List<Integer>> ability;

因为您正在尝试映射:

{
    "normal": [
        5,
        1,
        0
     ]
}