保存后懒惰被忽略

时间:2015-10-15 15:19:03

标签: java jackson spring-boot spring-data

我的控制器在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!");
}

它返回带有LAZY注释的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进行恢复,即使我这样做:

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

而不是

return persistedComment;    

2 个答案:

答案 0 :(得分:1)

在第一种情况下,新的注释对象被持久化并在同一个事务中获取。因此没有数据库调用来加载此对象。注释对象 持久化的是原样返回.Hibernate将持久化对象保留在一级缓存(休眠会话)中。

答案 1 :(得分:1)

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