2017-06-10 26 views
0

我正在尝试使用休息API和休眠来完成我的第一个JEE应用程序。我不知道如何以适当的方式做到这一点。我的意思是,我有实体用户Jax-RS-java rest api和hibernate

@Entity 
@XmlRootElement 
public class User { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 
    private String username; 
    private String password; 
    private String email; 
    private LocalDateTime lastDateOfLogin; 
    @OneToMany(fetch=FetchType.LAZY) 
    private List<Post> posts = new ArrayList<>(); 
    @OneToMany(fetch=FetchType.LAZY) 
    private List<Comment> comments = new ArrayList<>(); 
    @OneToMany(fetch=FetchType.LAZY) 
    private List<Like> likes = new ArrayList<>(); 
    @OneToMany(fetch=FetchType.LAZY) 
    private List<User> followers = new ArrayList<>(); 
    @OneToMany(fetch=FetchType.LAZY) 
    private List<User> following = new ArrayList<>(); 

,我有UserResource方法来获取一个用户

@GET 
    @Path("{id}") 
    public User getUser(@PathParam("id") long id) 
    { 
     return userService.getOne(id); 
    } 

现在我的问题是,当我试图让一个用户我得到的异常组织.hibernate.LazyInitializationException - 当然,我知道为什么,但问题是如何做到这一点,以适当的方式。在这个@GET我不需要这个OneToMany集合,因为当我想要E.g用户职位,我会打电话给用户/ 1 /职位的URL,我会收到所有的用户职位。

如何开发这种应用程序?我应该从用户实体中删除关系,并在需要时在用户的数据库文章中进行搜索?或者也许有另一种解决方案呢?

回答

1

如果这个特定的端点只关心用户的基本信息,而不关心你的数据库模型与系统中的其他对象有什么关系,那么你需要以某种方式阻止序列化过程查看这些属性。

如果它是一个您希望始终忽略的字段,那么可以使用@XmlTransient对其进行注释,但这是一个在生成时确定并且不能在运行时修改的决定。对于您需要动态地影响系列化一步的情况下,你可以看看这两篇文章:

  1. How to Conditionally serialize with JAXB or Jackson
  2. Jacksons JsonViewMOXy's external mapping-files

另一种方法是修改您服务为特定视图返回一个类实例,该实例只包含要编组到输出XML中的属性。这可以很容易地与一个JPA select new查询的方法实现:

SELECT new com.company.app.BasicUser(u.userName, other attributes) FROM User u 
WHERE u.id = :id 

现在你的XML编组将基于BasicUser,而不是你的域实体User,其中该BasicUser没有任何关联或属性,你不希望为该特定视图序列化。