Dari konsol reaksi saya mendapat ralat "Tidak dapat memuatkan sumber: Pelayan bertindak balas dengan status 500 ()" menunjuk ke url ":8080/api/review-add"
Daripada bahagian belakang Spring Boot, saya mendapat mesej ralat "not-null property references null or transient value: com.reactspringboot.bookclubbackend.entity.Review.account"
Masalahnya ialah apabila melakukan permintaan POST di Posmen saya tidak mendapat ralat dan objek diposkan ke pangkalan data.
Ini ialah fail dari bahagian belakang Spring 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; } }
Semakan.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); } }
Dari bahagian hadapan 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;
Dalam badan posmen saya pilih mentah dan tetapkan kepada JSON dan apabila saya menggunakan permintaan POST ini kepada entiti "semakan" ia berfungsi:
{ "datePosted": "2023-07-26", "comment": "From postman.", "starRating": 5.0, "account": { "id": 1 }, "forum": { "id": 1 } }
Forum dengan id 1 dan akaun dengan id 1 wujud dalam pangkalan data.
Jika sesiapa boleh membantu saya atau menunjukkan kepada saya penyelesaian kepada masalah ini, saya amat berterima kasih. Saya sudah berhari-hari tersepit dengan masalah ini dan saya ketandusan idea.
Jika pelayan menjangkakan untuk menerima keseluruhan muatan:
Pelayan tidak akan menerimanya selepas anda melakukan perkara berikut:
Pelayan hanya akan menerima:
Apabila anda hanya ingin mengemas kini satu sifat dalam keadaan, kemas kini masih perlu memasukkan objek yang lain untuk mengekalkan keseluruhan objek:
atau:
By the way...alat penyahpepijatan penyemak imbas anda boleh membantu anda mempersempit masalah yang tepat ini. Anda boleh memerhatikan muatan dalam permintaan AJAX yang dihantar, pastikan ia bukan seperti yang anda jangkakan dan segera menolak semuakod bahagian pelayan sebagai punca masalah dan mula memfokuskan pada penyahpepijatan pihak klien.