我正在构建一个 RESTful 服务来查看服务器关系(一个服务器可以包含另一台服务器作为其父级)。该服务接受用于 CRUD 命令的 JSON 字符串。
我在我的服务器对象中使用@JsonIdentityInfo
和@JsonIdentityReference
,以便用户收到简化的 JSON 答案,如下所示:
{"hostname":"childhostname", "parent":"parenthostname"}
作为父母,我只获得父母的主机名而不是父母对象 - 这正是我想要的并且工作正常。
我的问题始于尝试反序列化更新命令(尝试更新父级时)。如果我发送这个:
curl -i -X POST -H 'Content-Type: application/json' -d '{"parent":"parenthostname"}' http://localhost:8080/myRestService/rest/servers/childhostname
什么都没有发生 - 不会设置父级。问题在于交付的 JSON 字符串:
{"parent":"parenthostname"}
调试hibernate 2.4.4源码后,发现我的JSON字符串生成了一个com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Could not resolve Object Id [parenthostname]
. 不会抛出此异常,但将返回 null。
当我删除@JsonIdentityInfo
and@JsonIdentityReference
时,这个 JSON 字符串可以正常工作,并且我的父级将被更新(但随后我会丢失我的简化答案并且还会出现无限循环问题)。
因此,如果我将我的 JSON 字符串调整为:
'{"parent":{"hostname":"parenthostname"}}'
更新工作正常。但我想让简化(展开)版本工作。有任何想法吗?我很感谢任何提示。
我正在使用休眠 4.2.4 和杰克逊 2.4.4
这是我的(简化的)服务器类:
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="hostname")
public class Server extends A_Hardware {
@NaturalId
@Column(name="hostname", nullable=false, unique=true)
private String hostname = null;
@ManyToOne
@JsonIdentityReference(alwaysAsId = true)
private Server parent = null;
@OneToMany(fetch = FetchType.LAZY, mappedBy="parent")
@JsonIdentityReference(alwaysAsId = true)
private Set<Server> childServers = new HashSet<Server>();
[...]
// standard getters and setters
这是我的 RESTful 服务的更新类:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
@Path("{hostname}")
public Response update(@PathParam("hostname") final String hostname, JsonParser json){
Server s = null;
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
try{
s = mapper.readValue(json, Server.class);
这是我在这里的第一个问题,所以如果我的问题可能不完全清楚,请不要过分评判我;)