Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Boot中双向一对多关系上的LazyInitializationException异常_Spring_Hibernate_Spring Data Jpa_Open Session In View - Fatal编程技术网

Spring Boot中双向一对多关系上的LazyInitializationException异常

Spring Boot中双向一对多关系上的LazyInitializationException异常,spring,hibernate,spring-data-jpa,open-session-in-view,Spring,Hibernate,Spring Data Jpa,Open Session In View,以下Spring引导服务方法在尝试向Post.addComment(Comment)中的Post添加Comment时抛出Hibernate的LazyInitializationException: 实体映射如下所示: import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persis

以下Spring引导服务方法在尝试向
Post.addComment(Comment)
中的
Post
添加
Comment
时抛出Hibernate的
LazyInitializationException

实体映射如下所示:

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Post {

    @Id
    @GeneratedValue
    private Long id;

    private String title;

    @Column(length = 4096)
    private String content;

    private LocalDateTime creationDate;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public LocalDateTime getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(LocalDateTime creationDate) {
        this.creationDate = creationDate;
    }

    public Long getId() {
        return id;
    }

    @OneToMany(
            mappedBy = "post",
            cascade = CascadeType.ALL,
            orphanRemoval = true
        )
    private List<Comment> comments = new ArrayList<>();


    public void addComment(Comment comment) {
        comments.add(comment);
        comment.setPost(this);
    }

    public List<Comment>getComments() {
        return this.comments;
    }



}
Comment
的post引用中的
ManyToOne
获取类型的
EAGER
LAZY
,似乎没有什么区别

我做错了什么?如何解决这个错误

根据@mckszcz建议的更改,现在在尝试从帖子中获取评论时,同一服务上的以下方法会引发一些反射异常:

/**
 * Returns a list of all comments for a blog post with passed id.
 *
 * @param postId id of the post
 * @return list of comments sorted by creation date descending - most recent first
 */
public List<CommentDto> getCommentsForPost(Long postId) {
    List<Comment> comments = postRepository.getOne(postId).getComments();
    List<CommentDto> result = new ArrayList<>();
    comments.forEach(comment -> {
        result.add(new CommentDto(comment.getId(), comment.getComment(), comment.getAuthor(), comment.getCreationDate()));
    });
    return result;
}
/**
*返回已传递id的博客文章的所有评论的列表。
*
*@param postId该帖子的id
*@返回按创建日期降序排序的注释列表-最近的第一个
*/
公共列表getCommentsForPost(长帖子){
List comments=postRepository.getOne(postId.getComments();
列表结果=新建ArrayList();
评论。forEach(评论->{
添加(newcommentdto(comment.getId(),comment.getComment(),comment.getAuthor(),comment.getCreationDate());
});
返回结果;
}

如果要返回方法的javadoc中描述的属于帖子的所有评论列表,需要将其更改为什么?

由于拥有方是这里的评论,您应该将
addComment
方法更改为:

 public Long addComment(NewCommentDto newCommentDto) {
            try {
                Post post = postRepository.findById(newCommentDto.getPostId()).get();

                Comment comment = new Comment();
                comment.setComment(newCommentDto.getContent());

                comment.setPost(post);
                comment = commentRepository.save(comment);
                return comment.getId();
            } catch (Exception e) {
                throw new IllegalArgumentException("There's no posts for given ID.");
            }

        }

因为拥有方在这里是Comment,所以您应该将
addComment
方法更改为:

 public Long addComment(NewCommentDto newCommentDto) {
            try {
                Post post = postRepository.findById(newCommentDto.getPostId()).get();

                Comment comment = new Comment();
                comment.setComment(newCommentDto.getContent());

                comment.setPost(post);
                comment = commentRepository.save(comment);
                return comment.getId();
            } catch (Exception e) {
                throw new IllegalArgumentException("There's no posts for given ID.");
            }

        }

结果表明,除了在
addComment
方法中重新排列代码以消除
LazyInitializationException
(如@mckszcz所指出的,由JPA由于错误的
拥有方
属性而抛出)之外:

为了解决服务的
getCommentsForPost(Long postId)
方法中的反射
InvocationTargetException
,还需要在
CommentRepository
中引入一个额外的查找方法(允许通过包含父项的ID搜索多个子项):

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {

    List<Comment> findByPostId(Long postId);

}
@存储库
公共接口CommentRepository扩展了JpaRepository{
列表findByPostId(长postId);
}
然后在错误的方法中引入该存储库周围的相应更改:

/**
 * Returns a list of all comments for a blog post with passed id.
 *
 * @param postId id of the post
 * @return list of comments sorted by creation date descending - most recent first
 */
public List<CommentDto> getCommentsForPost(Long postId) {
    List<Comment> commentsForPost = commentRepository.findByPostId(postId);
    //List<Comment> comments = postRepository.getOne(postId).getComments();
    List<CommentDto> result = new ArrayList<>();
    commentsForPost.forEach(comment -> {
        result.add(new CommentDto(comment.getId(), comment.getComment(), comment.getAuthor(), comment.getCreationDate()));
    });
    return result;
}
/**
*返回已传递id的博客文章的所有评论的列表。
*
*@param postId该帖子的id
*@返回按创建日期降序排序的注释列表-最近的第一个
*/
公共列表getCommentsForPost(长帖子){
List commentsForPost=commentRepository.findByPostId(postId);
//List comments=postRepository.getOne(postId.getComments();
列表结果=新建ArrayList();
commentsForPost.forEach(注释->{
添加(newcommentdto(comment.getId(),comment.getComment(),comment.getAuthor(),comment.getCreationDate());
});
返回结果;
}

这两项措施似乎解决了问题。

结果表明,除了在
addComment
方法中重新排列代码,以消除
懒散初始化异常
(正如@mckszcz所指出的,JPA由于错误的
拥有方
属性而抛出):

为了解决服务的
getCommentsForPost(Long postId)
方法中的反射
InvocationTargetException
,还需要在
CommentRepository
中引入一个额外的查找方法(允许通过包含父项的ID搜索多个子项):

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {

    List<Comment> findByPostId(Long postId);

}
@存储库
公共接口CommentRepository扩展了JpaRepository{
列表findByPostId(长postId);
}
然后在错误的方法中引入该存储库周围的相应更改:

/**
 * Returns a list of all comments for a blog post with passed id.
 *
 * @param postId id of the post
 * @return list of comments sorted by creation date descending - most recent first
 */
public List<CommentDto> getCommentsForPost(Long postId) {
    List<Comment> commentsForPost = commentRepository.findByPostId(postId);
    //List<Comment> comments = postRepository.getOne(postId).getComments();
    List<CommentDto> result = new ArrayList<>();
    commentsForPost.forEach(comment -> {
        result.add(new CommentDto(comment.getId(), comment.getComment(), comment.getAuthor(), comment.getCreationDate()));
    });
    return result;
}
/**
*返回已传递id的博客文章的所有评论的列表。
*
*@param postId该帖子的id
*@返回按创建日期降序排序的注释列表-最近的第一个
*/
公共列表getCommentsForPost(长帖子){
List commentsForPost=commentRepository.findByPostId(postId);
//List comments=postRepository.getOne(postId.getComments();
列表结果=新建ArrayList();
commentsForPost.forEach(注释->{
添加(newcommentdto(comment.getId(),comment.getComment(),comment.getAuthor(),comment.getCreationDate());
});
返回结果;
}

这两项措施似乎解决了问题。

你能解释一下
拥有方的含义吗?
请参考这篇文章:因为人们已经比我解释得更好了would@mckzcz:它似乎正在破坏其他反射调用,请看添加的代码。你能解释一下拥有方的含义吗?请参考这篇文章:因为人们已经比我解释得更好了would@mckzcz:它似乎正在破坏其他反射调用,请查看添加的代码。