我已经尝试了许多不同的解决方案,但没有任何作用。这是我现在拥有的:
我的数据看起来像这样的播放器:
{
"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;
}
,然后:
@Data
@Entity
@Table(name = "abilities")
@EntityListeners(AuditingEntityListener.class)
public class Abilities {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@ElementCollection(targetClass = Integer.class )
private List<Integer> ability;
}
我遇到的错误:
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.project.myapp.entity.Abilities` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.project.myapp.entity.Abilities` out of START_ARRAY token
at [Source: (PushbackInputStream); line: 1, column: 1067708] (through reference chain: java.lang.Object[][911]> com.project.myapp.entity.Player["weaponAbilities"]->java.util.LinkedHashMap["normal"])
首先,错误是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;
}
然后,这将将映射字段存储到一个单独的表中,其中键存储在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;
}
}
,但这完全取决于您对此列表的要求,您是否有大量元素,是否要查询它,等等,这可能会对您是否会影响您是否会影响使用中间实体,或将其执行到单列中(如下所示(。
尝试使用:
private Map<String, List<Integer>> ability;
因为您正在尝试映射:
{
"normal": [
5,
1,
0
]
}