我有一个项目与春季启动和休眠。一切工作良好,从数据库选择数据,但我有插入实体后的问题。实体关系在插入后不能获取。我尝试了JpaRepositorysaveAndFlush
,但没有工作。我也试过findById
没有工作。如何解决这个问题?
我的实体;
@Entity
@Table(name = "Comment")
@Data
@ApiModel(value = "Comment Model")
public class Comment {
public static Comment createCommentFromCommentPostRequest(CommentPostRequest commentPostRequest){
Comment comment = new Comment();
comment.setPostId(commentPostRequest.getPostId());
comment.setUsersId(commentPostRequest.getUsersId());
comment.setText(commentPostRequest.getText());
return comment;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@ApiModelProperty(value = "Comment model autogenerated Id value")
private Long id;
@Column(name = "usersId",nullable = false)
@ApiModelProperty(value = "User Id for describe who commented post")
private Long usersId;
@Column(name = "postId",nullable = false)
@ApiModelProperty(value = "Post Id for describe which post commented")
private Long postId;
@Column(name = "text",length = 500)
@ApiModelProperty(value = "define post content")
private String text;
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "usersId",insertable = false,updatable = false,nullable = false)
private Users users;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "postId",insertable = false,updatable = false,nullable = false)
@JsonIgnore
@OnDelete(action = OnDeleteAction.CASCADE)
private Post post;
}
我的库;
public interface CommentRepository extends PagingAndSortingRepository<Comment,Long> {
List<Comment> findAllByPostId(Long postId, Pageable pageable);
}
My Service Method;
public Comment saveOneComment(CommentPostRequest commentPostRequest) {
//TODO: implement validation
Comment commentToSave = Comment.createCommentFromCommentPostRequest(commentPostRequest);
commentToSave= commentRepository.save(commentToSave);
//I tried JPA repository saveAndFlush
return commentRepository.findById(commentToSave.getId()).orElse(null);
}
我的控制器;使用saveOneComment endpoint
@RestController
@RequestMapping("/api/comment")
@ApiOperation(value = "Comment api controller")
public class CommentController {
CommentService commentService;
public CommentController(CommentService commentService) {
this.commentService = commentService;
}
@GetMapping("/{pageNo}/{pageSize}")
public List<Comment> getAllComments(@PathVariable int pageNo,@PathVariable int pageSize){
return Streamable.of(commentService.getAllComments(pageNo,pageSize)).toList();
}
@GetMapping("/{commentId}")
public Comment findCommentById(@PathVariable Long commentId){
return commentService.findById(commentId);
}
@GetMapping("/postId={postId}/{pageNo}/{pageSize}")
public List<CommentResponse> getAllCommentsByPostId(@PathVariable Long postId,@PathVariable int pageNo,@PathVariable int pageSize){
return commentService.getAllCommentsByPostIdAsCommentResponse(postId,pageNo,pageSize);
}
@PostMapping
public Comment saveOneComment(@RequestBody CommentPostRequest commentPostRequest){
return commentService.saveOneComment(commentPostRequest);
}
@PutMapping("/{commentId}")
public Comment putOneComment(@PathVariable Long commentId,@RequestBody CommentPostRequest commentPostRequest){
return commentService.putOneCommentById(commentId,commentPostRequest);
}
@DeleteMapping("/{commentId}")
public void deleteOneComment(@PathVariable Long commentId){
commentService.deleteById(commentId);
}
}
Comment(id=32, usersId=2, postId=2, text=ddwad, users=null, post=null)
插入和查找之后,users和post为空。当我运行getAllCommentsByPostId方法时,一切都很好。
插入后,只在控制台插入查询。select语句没有任何查询
insert
into
Comment
(postId, text, usersId)
values
(?, ?, ?)
我认为这里的问题是数据总是从hibernate缓存中获取。如果启用SQL查询,则在调用此代码时不会看到任何选择查询发生-
return commentRepository.findById(commentToSave.getId()).orElse(null);
虽然,必须有一个更好的方法来处理这个。我能想到的唯一方法就是用EntityManager.clear ()或EntityManager.refresh (commentToSave).
这些技术将强制hibernate分离托管实体并再次从db中获取数据。我更喜欢刷新,因为它只刷新传递的实体。
现在JPA repos不公开实体管理器或clear/flush方法。您必须做一个CustomRepo Implementation来在所有的repo上公开刷新方法。检查这篇文章的一步一步的指导https://dzone.com/articles/adding-entitymanagerrefresh-to-all-spring-data-rep
最后,您需要在保存和刷新后调用refresh,像这样-
public Comment saveOneComment(CommentPostRequest commentPostRequest) {
//TODO: implement validation
Comment commentToSave = Comment.createCommentFromCommentPostRequest(commentPostRequest);
commentToSave= commentRepository.saveAndFlush(commentToSave);
commentRepository.refresh(commentToSave);
return commentToSave;
}
你必须在提交事务后重新加载对象,我的意思是在事务之外维护关系
@PostMapping
public Comment saveOneComment(@RequestBody CommentPostRequest commentPostRequest){
Long id= commentService.saveOneComment(commentPostRequest);
return commentService.loadCommentById(id);
}
````