2015-10-15 50 views
0

我的控制器在Spring Boot上行为不同,我不知道为什么。我有这样的模式:保存后懒惰被忽略

@Entity 
@Table(name = "comments") 
@JsonInclude(JsonInclude.Include.NON_EMPTY) 
public class Comment { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @Column(nullable = false) 
    private boolean anonymous = false; 

    @Column(nullable = false, length = 150) 
    private String text; 

    @Temporal(TemporalType.TIMESTAMP) 
    @Column(nullable = false) 
    private Date date; 

    @ManyToOne(fetch = FetchType.EAGER) 
    private User user; 

    @ManyToOne(fetch = FetchType.LAZY) 
    private Post post; 

    // Getters and Setters 
} 

在我控制我做的:

@RequestMapping(value = "", 
      method = RequestMethod.POST, 
      produces = MediaType.APPLICATION_JSON_VALUE) 
public Object createComment(Comment comment, HttpServletRequest request){ 
    comment.setUser(userService.findByUsername(UserUtil.readUsernameFromUrlToken(request))); 

    Comment persistedComment = commentService.save(comment); 
    if(persistedComment != null){ 
     if(persistedComment.isAnonymous()){ 
      persistedComment.setUser(null); 
     } 
     return persistedComment; 
    } 
    return new Error(Error.NOT_CREATED, "Comment not created!"); 
} 

它返回一个annotaded懒的post。但是,当我在另一个控制器读取,它返回预期的结果(不懒post

@RequestMapping(value = "/{id}/comments", 
      method = RequestMethod.GET, 
      produces = MediaType.APPLICATION_JSON_VALUE) 
public Object findCommentsByPostId(@PathVariable("id") long postId){ 
    List<Comment> comments = commentService.findByPostId(postId); 
    for(Comment comment : comments){ 
     if(comment.isAnonymous()){ 
      comment.setUser(null); 
     } 
    } 
    return comments; 
}  

在此请求映射,它仅返回user,符合市场预期。 我不知道为什么在第一个将其与懒惰post resturns,就算我做的:

return commentService.findById(persistedComment.getId()); 

,而不是

return persistedComment;  
+0

如果您调用第一个控制器,该帖子是否也包含在JSON中?如果是这样,那么邮政领域当然会充满这些数据。由于持久化对象随后存储在实体管理器中,所以在调用findById方法时将返回此对象。 – dunni

+0

感谢您的答案,是的,它被添加,因为它来自请求'postId'来填充关系。所以可以理解,也会返回'post'。但是,即使使用'return commentService.findById(persistedComment.getId());',为什么它会返回'post',因为它只是使用持久化对象的'id'作为另一个请求的地址它是否正确? – augustoccesar

+0

AFAIK如果您在实体管理器中拥有一个托管对象(您拥有该托管对象,因为您已经在该方法中保留了该注释),并且您通过ID检索该对象,则将使用实体管理器中的对象,该对象仍包含帖子。 – dunni

回答

1

如果您调用第一个控制器,并且该帖子也包含在JSON中,那么帖子字段当然会填充该数据。由于持久化对象然后作为管理对象存储在实体管理器中,因此当您调用findById方法(实体管理器或Hibernate会话用作第一级缓存)时,将返回此对象。

1

在你的第一个案例一个新的评论对象持久化和因为没有数据库调用来加载这个对象。持久化的注释对象 将按原样返回.Hibernate将持久对象保存在第一级缓存(hibernate会话)中。