我的设置:
JBoss AS 7.1.1 使用 JPA、Hibernate(连接到 PostgreSQL)、RESTEasy、Jackson 1.9.2 for JSON、EclipseLink MOXy 2.4.1 for XML
我有两个实体 - Group和User。一个组包含许多用户(一对多)。我声明了与 JPA 注释的双向关系(见下文),因此我必须通过使用@JsonManagedReference
/ @JsonBackReference
(对于 JSON)和@XmlInverseReference
(对于 XML)来防止循环。这可以按预期工作,除非我尝试通过 REST 创建用户,否则在使用 XML 时我无法将她分配给组。使用 JSON 时,它可以工作:
Jackson JSON工作(成功添加 Jane Doe 并将她置于第 5 组):
POST request to /user
Content-Type: application/json
Accept: application/json
Body: {"name":"Jane Doe", "group":{"id":5}}
Response:
{
"id": 12,
"name":"Jane Doe"
}
Hibernate: insert into users (group_id, name, id) values (5, 'Jane Doe', 12)
这是添加 Jackson 用户后的 GroupEndpoint 响应:
GET request to /group
Accept: application/json
Response:
[{"id":5,"name":"My User Group","users":[{"id":12,"name":"Jane Doe"}]}
MOXy XML不起作用(Jane Doe 是孤儿):
POST request to /user
Content-Type: application/xml
Accept: application/xml
Body: <name>Jane Doe</name><group><id>5</id></group>
Response:
<user><name>Jane Doe</name><id>12</id></user>
Hibernate: insert into users (group_id, name, id) values (null, 'Jane Doe', 12)
这是使用 MOXy 添加用户后的 GroupEndpoint 响应:
GET request to /group
Accept: application/xml
Response:
<collection>
<group><id>5</id><name>My User Group</name></group>
</collection>
我试过了@XmlID
,@XmlIDREF
同样的问题。 @XmlTransient
同样会忽略 marshal 和 unmarshal 上的子父关系。
我的问题:
如何通过用户 REST 端点将用户添加到组,而不需要 MOXy 忽略新用户的组字段(标记为 @XmlInverseReference)?
我应该增加 REST 端点、创建 XmlAdapter 还是编写自定义序列化程序?我是否缺少具有不同注释的简单解决方案? 是否有一种完全不同的方法可以通过首选的 REST 公开关系对象? 任何帮助深表感谢。
这是组实体:
@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Group implements Serializable {
@Id
private Long id;
@Column
private String name;
@OneToMany(mappedBy="group", cascade=CascadeType.ALL)
@JsonManagedReference("group-user")
private Set<User> users;
// Omitting getters and setters etc...
}
这是用户实体:
@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
@Id
private Long id;
@Column
private String name;
@ManyToOne
@JsonBackReference("group-user")
@XmlInverseReference(mappedBy="users")
private Group group;
// Omitting getters and setters etc...
}
这是用户 REST 端点:
@Stateful
@Path("/user")
@TransactionAttribute
public class UserEndpoint {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
@POST
@Consumes({"application/xml","application/json"})
public User create(User entity) {
em.joinTransaction();
em.persist(entity);
return entity;
}
}
这是 Group REST 端点(包括在内以表明需要防止循环):
@Stateful
@Path("/group")
@TransactionAttribute
public class GroupEndpoint {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
@GET
@Produces({"application/xml","application/json"})
public List<Group> listAll() {
final List<Group> results = em.createQuery("SELECT x FROM Group x").getResultList();
return results;
}
}
这是使用Jackson添加用户后的 GroupEndpoint MOXy响应,以测试周期:
GET request to /group
Accept: application/xml
Response:
<collection>
<group>
<id>5</id>
<name>My User Group</name>
<users><id>12</id><name>Jane Doe</name></users>
</group>
</collection>