我试图测试Hibernate的一对多关系。我将Post和PostComment实体定义如下: 的 Post.java
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "post")
public class Post {
@Id
@Column(name="post_id")
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long postId;
@Column(name="title")
private String title;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "post",
orphanRemoval = true)
private List<PostComment> comments = new ArrayList<>();
public Post() {};
public Post(String title) {
this.title = title;
}
// Add getter and setter
}
PostComment.java
import javax.persistence.*;
@Entity
@Table(name = "post_comment")
public class PostComment {
@Id
@Column(name="comment_id")
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long commentId;
@Column(name="review")
private String review;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;
public PostComment() {};
public PostComment(String review) {
this.review = review;
}
// Add getter and setter
}
PostRepository.java
public interface PostRepository extends JpaRepository<Post,Long> {
}
和 db-changelog.xml
<changeSet id="1" author="dev">
<createTable tableName="post_comment">
<column name="comment_id" type = "bigint">
<constraints nullable="false" primaryKey="true"></constraints>
</column>
<column name="review" type="varchar(255)"></column>
</createTable>
<createTable tableName="post">
<column name="post_id" type="bigint">
<constraints nullable="false" primaryKey="true"></constraints>
</column>
<column name="title" type = "varchar(255)"></column>
</createTable>
</changeSet>
然后,我使用SpringJUnit在PostServiceITTest.java中添加一个新帖子
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.util.Arrays;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {Application.class})
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ActiveProfiles("devmock")
public class PostServiceITTest {
@Autowired
private PostRepository postRepository;
@Test
public void testAddPost(){
Post post = new Post(" Post 1");
PostComment postComment1 = new PostComment(" Post comment 1");
PostComment postComment2 = new PostComment(" Post comment 2");
post.setComments(Arrays.asList(postComment1,postComment2));
postRepository.save(post);
}
}
不幸的是,测试抛出了与null-violate约束相关的Postgresql错误:
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "post_id" violates not-null constraint
Detail: Failing row contains (null, Post 1).
我非常感谢你的时间。
答案 0 :(得分:0)
您似乎没有传递post_id
的值。
答案 1 :(得分:0)
在PostComment
课程中,您有一个字段private Post post
。我怀疑你是否正在设置那个领域。
一个选项是将Post post
作为构造函数参数添加到PostComment
类(以及默认构造函数),并将其与Post
对象一起实例化,如下所示:
public PostComment(String review, Post post) {
this.review = review;
this.post = post;
}
在构建对象时使用:
PostComment postComment1 = new PostComment(" Post comment 1", post);
而不是
PostComment postComment1 = new PostComment(" Post comment 1");
或者另一种方法是在Post
类中添加脚手架代码,如:
public void addPostComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
并在将PostComment
更新/添加到Post
类的列表时使用此方法。
答案 2 :(得分:0)
我已经解决了该问题,方法是删除现有数据库并使用spring.jpa.hibernate.ddl-auto=create-drop
生成一个新数据库。在我看来。最好在每次对实体结构进行一些重大更改时都执行此操作。完成后,请改回spring.jpa.hibernate.ddl-auto=update
。
答案 3 :(得分:0)
以下代码可能有效;您也可以在 child 中设置父引用...
{ Post post = new Post(" Post 1");
PostComment postComment1 = new PostComment(" Post comment 1");
postComment1.setPost(post); // < -- here
PostComment postComment2 = new PostComment(" Post comment 2");
postComment2.setPost(post); // < -- here
post.setComments(Arrays.asList(postComment1,postComment2));
postRepository.save(post);
}
如果你使用 lombok 生成 toString() 方法,请排除 postComment.post 以避免无限循环(导致 stak 溢出);
@ToString(exclude = { "post" })
public class PostComment{
// ...
}