以下 Spring Boot 服务方法LazyInitializationException
在尝试将 a 添加Comment
到 aPost
时会引发 Hibernate post.addComment(comment)
:
@Service
public class CommentService {
@Autowired
private PostRepository postRepository;
@Autowired
private CommentRepository commentRepository;
//.....
/**
* Creates a new comment
*
* @param newCommentDto data of new comment
* @return id of the created comment
*
* @throws IllegalArgumentException if there is no blog post for passed newCommentDto.postId
*/
public Long addComment(NewCommentDto newCommentDto) {
try {
Post post = postRepository.findById(newCommentDto.getPostId()).get();
Comment comment = new Comment();
comment.setComment(newCommentDto.getContent());
post.addComment(comment);
comment = commentRepository.save(comment);
return comment.getId();
} catch (Exception e) {
throw new IllegalArgumentException("There's no posts for given ID.");
}
}
实体映射如下:
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;
}
}
import java.time.LocalDateTime;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
@Entity
public class Comment {
@Id
@GeneratedValue
private Long id;
private String comment;
private String author;
private LocalDateTime creationDate;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "post_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private Post post;
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public LocalDateTime getCreationDate() {
return creationDate;
}
public void setCreationDate(LocalDateTime creationDate) {
this.creationDate = creationDate;
}
}
的或的帖子引用的ManyToOne
获取类型似乎没有什么区别。EAGER
LAZY
Comment
我在这里做错了什么?如何解决这个错误?
随着@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;
}
如方法的 javadoc 中所述,需要将其更改为返回属于帖子的所有评论的列表?