从react控制台,我收到错误消息“Failed to load resource:服务器以500()的状态响应”指向url“:8080/API/review-add”
从spring Boot 后端我得到错误消息“not-null property references a null or transient value:com.reactspringboot.bookclubbackend.entity.Review.account”
问题是当在postman中执行POST请求时,我没有得到错误,对象被发送到数据库中。
以下是Sping Boot 后端的文件:
Forum.java
@Entity
@Table(name="Forum")
public class Forum {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="book_name")
private String bookName;
@Column(name="book_image")
private String bookImage;
@Lob
@Column(name="description")
private String description;
@OneToMany(mappedBy = "forum", cascade = CascadeType.ALL)
private List<Review> reviews;
public Forum() {
}
public Forum(String bookName, String bookImage, String description, List<Review> reviews) {
this.bookName = bookName;
this.bookImage = bookImage;
this.description = description;
this.reviews = reviews;
}
public long getId() {
return id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookImage() {
return bookImage;
}
public void setBookImage(String bookImage) {
this.bookImage = bookImage;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
// using 'JsonProperty' to prevent infinite recursion
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
public List<Review> getReviews() {
return reviews;
}
public void setReviews(List<Review> reviews) {
this.reviews = reviews;
}
}
字符串
Account.java
@Entity
@Table(name="account")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="account_name")
private String accountName;
@Column(name="password")
private String password;
@Column(name="email")
private String email;
@Column(name="profile_image")
private String profileImage;
@Column(name="role")
private String role;
@Column(name="date_joined")
@CreationTimestamp
private Date dateJoined;
@OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
private List<Review> reviews;
public Account() {
}
public Account(String accountName, String password, String email, String profileImage, String role, Date dateJoined, List<Review> reviews) {
this.accountName = accountName;
this.password = password;
this.email = email;
this.profileImage = profileImage;
this.role = role;
this.dateJoined = dateJoined;
this.reviews = reviews;
}
public long getId() {
return id;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getProfileImage() {
return profileImage;
}
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Date getDateJoined() {
return dateJoined;
}
public void setDateJoined(Date dateJoined) {
this.dateJoined = dateJoined;
}
// using 'JsonProperty' to prevent infinite recursion
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
public List<Review> getReviews() {
return reviews;
}
public void setReviews(List<Review> reviews) {
this.reviews = reviews;
}
}
型
Review.java
@Entity
@Table(name="review")
public class Review {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="date_posted")
@CreationTimestamp
private Date datePosted;
@Lob
@Column(name="comment")
private String comment;
@Column(name="star_rating")
private double starRating;
//@JsonIgnore
@ManyToOne
@JoinColumn(name = "account_id",nullable = false, insertable = true, updatable = true)
private Account account;
//@JsonIgnore
@ManyToOne
@JoinColumn(name = "forum_id",nullable = false, insertable = true, updatable = true)
private Forum forum;
public Review() {
}
public Review(Date datePosted, String comment, double starRating, Account account, Forum forum) {
this.datePosted = datePosted;
this.comment = comment;
this.starRating = starRating;
this.account = account;
this.forum = forum;
}
public long getId() {
return id;
}
public Date getDatePosted() {
return datePosted;
}
public void setDatePosted(Date datePosted) {
this.datePosted = datePosted;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public double getStarRating() {
return starRating;
}
public void setStarRating(double starRating) {
this.starRating = starRating;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public Forum getForum() {
return forum;
}
public void setForum(Forum forum) {
this.forum = forum;
}
}
型
ReviewRepository.java
@CrossOrigin(origins = "http://localhost:3000")
public interface ReviewRepository extends JpaRepository<Review, Long> {
@Query(value = "SELECT * FROM Review r where r.forum_id = :forum_id", nativeQuery = true)
public List<Review> getReviewsUsingForumId(@Param("forum_id") Long forum_id);
}
型
ReviewController.java
@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("/api/")
public class ReviewController {
@Autowired
private ReviewRepository reviewRepository;
// create review rest api
//@CrossOrigin(origins = "http://localhost:3000")
@PostMapping("/review-add")
public Review createReview(@RequestBody Review review) {
return reviewRepository.save(review);
}
@GetMapping("/forum-reviews/{forumId}")
public List<Review> getReviewsByForumId(@RequestBody @PathVariable Long forumId) {
return reviewRepository.getReviewsUsingForumId(forumId);
}
}
型
React前端
PostComponent.js
function PostComponent() {
// right now only using static data for testing
const [review, setReview] = useState({datePosted: "2023-07-26", comment: "",
starRating: 5.0,
account: {
id: 1
},
forum: {
id: 1
}});
const postURL = "http://localhost:8080/api/review-add";
function changeHandler (event) {
setReview({comment: event.target.value});
}
function submit(event) {
event.preventDefault();
axios.post(postURL, review)
}
useEffect(() => {
console.log(review.comment)
}, [review]);
return (
<div>
<div className="container">
<h2>Post Review</h2>
<form onSubmit={(event) => submit(event)}>
<div className="form-group">
<label>Comment</label>
<input placeholder="Commet here" name="comment" className="form=control"
value={review.comment} onChange={changeHandler}/>
</div>
<button>Submit</button>
</form>
</div>
</div>
)
}
export default PostComponent;
型
在postman body中,我选择raw并设置为JSON,当我使用这个POST请求“Review”实体时,它工作:
{
"datePosted": "2023-07-26",
"comment": "From postman.",
"starRating": 5.0,
"account": {
"id": 1
},
"forum": {
"id": 1
}
}
型
ID为% 1的论坛和ID为% 1的帐户在数据库中存在。
如果有人能帮助我或指出我解决这个问题,我将不胜感激。我在这个问题上被困了好几天,已经无计可施了。
1条答案
按热度按时间js4nwp541#
如果服务器需要整个payload:
字符串
在你这样做之后,它不会收到:
型
它只会收到:
型
当您只想更新状态中的一个属性时,更新仍然需要包括对象的其余部分,以便保留整个对象:
型
或者:
型
顺便说一句您的浏览器的调试工具将帮助您缩小这个确切的问题。您可以观察 AJAX 请求中发送的有效负载,发现它不是您所期望的,并立即排除所有服务器端代码作为罪魁祸首,并开始专注于客户端调试。