【问题标题】:Error - not-null property references a null or transient value错误 - 非空属性引用空值或瞬态值
【发布时间】:2021-09-01 10:10:36
【问题描述】:

我是春天的新手。我制作了一个基于两个表之间关系的 API,为此使用 OneToMany 注释和用于 API 测试我有邮递员。我的目标是将请求的数据保存在下面提到的两个单独的实体中。当我尝试在邮递员中发布数据时: 1-3 字段与 Post 实体相关,而 text 字段属于 Comment 实体(cmets 是加入字段)

{
"title": "Post1",
"description": "Post 1 description",
"content": "Post 1 content",
"comments": [
    {
        "text": "Java best selling book"
    },
    {
        "text": "Exploring spring boot"
    }
]

}

我收到如下错误:

Hibernate: insert into posts (content, description, title) values (?, ?, ?)
2021-09-01 11:55:09.786 TRACE 9884 --- [nio-8089-exec-2] o.h.type.descriptor.sql.BasicBinder      
: binding parameter [1] as [VARCHAR] - [Post 1 content]
2021-09-01 11:55:09.786 TRACE 9884 --- [nio-8089-exec-2] o.h.type.descriptor.sql.BasicBinder      
: binding parameter [2] as [VARCHAR] - [Post 1 description]
2021-09-01 11:55:09.786 TRACE 9884 --- [nio-8089-exec-2] o.h.type.descriptor.sql.BasicBinder      
: binding parameter [3] as [VARCHAR] - [Post1]
2021-09-01 11:55:09.815 ERROR 9884 --- [nio-8089-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    
: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 
[Request processing failed; nested exception is 
org.springframework.dao.DataIntegrityViolationException: not-null property references a null 
or transient value : com.techspring.entity.Comment.post; nested exception is 
org.hibernate.PropertyValueException: not-null property references a null or transient value : 
com.techspring.entity.Comment.post] with root cause

我的 MVC 如下:

Post.java

@Entity
@Table(name = "posts")
public class Post {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String title;
  private String description;
  private String content;
  @OneToMany(cascade = CascadeType.ALL,
        fetch = FetchType.LAZY,
        mappedBy = "post")
  private Set<Comment> comments = new HashSet<>();

  GET, SET;

Comment.java

@Entity
@Table(name = "comments")
public class Comment {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String text;

  @ManyToOne(fetch = FetchType.LAZY, optional = false)
  @JoinColumn(name = "post_id", nullable = false)
  private Post post;

  Get, Set;

PostController.java

休息控制器 公共类 PostController {

@Autowired
private PostRepository postRepository;

@PostMapping("/posts")
public Post createPost(@Valid @RequestBody Post post) {
    return postRepository.save(post);
}      

CommentController.java

@RestController
public class CommentController {

@Autowired
private CommentRepository commentRepository;

@Autowired
private PostRepository postRepository;


@PostMapping("/posts/{postId}/comments")
public Comment createComment(@PathVariable (value = "postId") Long postId,
                             @Valid @RequestBody Comment comment) {
    return postRepository.findById(postId).map(post -> {
        comment.setPost(post);
        return commentRepository.save(comment);
    }).orElseThrow(() -> new ResourceNotFoundException("PostId " + postId + " not found"));

感谢您的帮助。

【问题讨论】:

    标签: java spring-boot


    【解决方案1】:

    您的操作方式Comment comment 是一个新的临时实体,它与已维护的post 实体相关。在保存期间,第一次休眠将尝试更新帖子以匹配该评论,但该评论尚不存在,因此失败。

    对您来说更好的工作流程如下。

    返回带有所有评论的帖子更有意义,并且只需将新评论附加到已经存在的帖子中。这样,hibernate 将首先创建评论实体,然后将其与已经存在且不会遇到任何问题的帖子相关联。

    @PostMapping("/posts/{postId}/comments")
    public Post createComment(@PathVariable (value = "postId") Long postId,
                                 @Valid @RequestBody Comment comment) {
        Optional<Post> postOpt = postRepository.findById(postId);
          if (postOpt.isPresent()) {
            comment.setPost(postOpt.get()); <----------------
            postOpt.get().getComments().add(comment);
            postRepository.save(postOpt.get());
            return postOpt.get();
          } else {
            throw new ResourceNotFoundException("PostId " + postId + " not found");
          }
    
       }
    

    【讨论】:

    • 谢谢,也许您在第 6 行的“post”之前遗漏了一些内容。请您改写一下吗?
    • 谢谢,但我得到同样的错误:org.hibernate.PropertyValueException: not-null property references a null or transient value : com.techspring.entity.Comment.post
    • 是的,我在两个实体中都做过
    • @TheKash 我又添加了 1 行可能会解决问题的行,请检查一下
    • @TheKash 的简单出路是 @JoinColumn(name = "post_id", nullable = false) remove nullable = false 这是 Hibernate 的工作流程,它违反了该约束以保持映射对齐并且它失败了
    【解决方案2】:

    我遇到了类似的问题,要解决它,您需要将父对象设置为子对象。 会是这样的

    post.getComments().stream().forEach(c -> c.setPost(post));
    

    【讨论】:

      猜你喜欢
      • 2017-04-25
      • 1970-01-01
      • 2011-12-23
      • 2010-10-08
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多