JAX-RS JSON serialization loop with JPA entities
我正在使用NETBeaS 7.4开发GelasFISH 4上的典型JavaEE 7应用程序。我有一组具有各种关系的JPA实体。因为这可能是一个众所周知的问题,所以当我试图使用JAX-RS服务公开与另一个实体具有双向关系的实体时,我面临一个问题(很可能是由序列化循环引起的)。
我一直在寻找解决方案。显然,解决这一问题的最干净的方法是使用Jackson提供商,而不是Jersey内置提供商。然而,这对我来说并不成功。我可能在中间做了一些错误的事情,任何暗示都会很感激。
第一实体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Entity public class User implements Serializable { @Id private long id; ... @OneToMany( mappedBy ="owner", cascade = CascadeType.ALL ) private List<Playlist> playlists; ... } |
第二实体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Entity public class Playlist { @Id @GeneratedValue private long id; ... @NotNull @ManyToOne private User owner; ... } |
号
JAX-RS服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Path("/user") @Stateless public class UserResource { @Inject private UserService userService; @GET @Path("/{username}") @Produces(MediaType.APPLICATION_JSON) public Response getUser(@PathParam("username") String username) { return Response.ok(userService.getUser(username)).build(); } } |
我在类路径中下载并包含了最新的杰克逊二进制文件(jackson-core-2.3.1.jar),在部署应用程序时,我可以在Glassfish服务器日志中看到与杰克逊相关的内容。如果返回的用户实体没有任何关联的播放列表,则一切正常。但是,对于指定用户的一个或多个播放列表,将返回HTTP 500错误,并且Glassfish服务器日志中不会显示任何内容。
事先谢谢你的帮助。
更新
在多次来回之后。我还是不能让杰克逊工作。我搬到了Wildfly(JBoss8),我不能让它使用提供的杰克逊版本而不是内置版本。无论在类路径中添加了哪个版本的Jackson(有或没有Maven),错误始终指示org.codehaus.jackson.*。
找到@mgorgon答案很有用。
在我的例子中,我希望将Hibernate与Jersey一起使用,但只在restfull JSON Web服务中检索关系ID(而不是加载整个对象)。
最后我为ID创建了一个字段:
1 2 3 4 5 6 7 | @JsonIgnoreProperties({"parent"}) // this ignores the object for json serialization public class Object{ private int id; private AnotherObj parent; @Transient // this ignores the properties for hibernate mapping, cause we want to use the parent.getId() instead. You may have to put it in your get too private ind parent_id; } |
号
然后,在ObjectDAO查询中,如果需要从关系中获取父ID,可以将父ID定义为父ID:
类似于"从用户u id=父u id")的文件。
对于您的所有查询,您必须执行此操作:
因为
当然,你应该使用懒惰的关系(否则它会加载obj)。它工作是因为父对象表的列是父对象表的列,所以不需要调用父对象表。
当您有很多关系,但只需要查询ID时,这很有用。
修改您的
1 2 3 |
当你的杰克逊试图序列化有用户的播放列表的用户时,他正在运行到递归…