Configured the association between objects using Springboot JPA.I want to be able to post comments on my blog.

Asked 2 years ago, Updated 2 years ago, 93 views

@ManyToOne, @OneToMany I want to be able to add comments (comment class) functionality to blogs (blog class), but I get an error with the object "comment field error" in the field "blog" and no comments are displayed.

ブログ Blogs have multiple comments (1-to-many), and comments are linked to one blog (many-to-many).
②Create each repository interface in blog, comment.
③Created a comment object and added it to the Model when displaying the blog page on the controller.Use the comment repository interface to save the contents submitted by adding a post date and time.

I am using MySQL from XAMPP.The blog_id should have been generated in the comment table and the relationship should have been completed, but the results are not displayed as expected.
I thought there might be a typo or argument error in the field, so I checked it, but there was no mistake.
Please let me know.

application.properties

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/database name ?serverTimezone=JST
spring.datasource.username=username
spring.datasource.password=password

blog.java

package com.example.demo;

import java.time.LocalDateTime;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import lombok.Data;

@Entity// Indicates that the class (entity) is to be stored in the table in JPA.
@ Data
public class Blog {
    @Id // The primary key (main key) field in the corresponding table
    @GeneratedValue(strategy=GenerationType.AUTO)//Automatically generates primary key values in serial numbers.
    private Integer id;

    private String title;

    privateLocalDateTime postDateTime;

    @Column(length=1000) // Add @Column to control the columns in the table.Set the field length from the default of 255 to 1000.
    private String contents;
                                 // One-to-many relationships. Blogs have multiple comments.
    @OneToMany(mappedBy="blog")// The mappedBy argument specifies the name that the other party refers to itself.
    private List <Comment > Comments;
}

comment.java

package com.example.demo;

import java.time.LocalDateTime;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import lombok.Data;

@Entity
@ Data
public class Comment {
@Id
@GeneratedValue (strategy=GenerationType.AUTO)
private Integer id;
private String text;
privateLocalDateTime postDateTime;

@ManyToOne // Many to one relationship.Comment is linked to a blog.
private Blog;

}

BlogRepository.java

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface BlogRepository extensions JpaRepository < Blog, Integer > {

}

CommentRepository.java

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface CommentRepository extensions JpaRepository <Comment, Integer > {

}

SampleController.java

package com.example.demo;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.announcement.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.announcement.GetMapping;
import org.springframework.web.bind.announcement.PathVariable;
import org.springframework.web.bind.announcement.PostMapping;

@ Controller
public class SampleController {

    @Autowired// Repository interface references, additions, updates, and more are predefined.Simply list the records in the table by using the findAll method.
    private BlogRepository blogRepository;
    @Autowired
    private CommentRepository commentRepository;

    @ GetMapping("/")
    public String index (Model model) {
        List<Blog>blogs=blogRepository.findAll();
        model.addAttribute("blogs", blogs);
        return "index";
    }

    @ GetMapping ("/form")
    public String form (Blog blog) {
        return "form";
    }

    @ PostMapping ("/create")
    public String create (Blog blog) {
        blog.setPostDateTime(LocalDateTime.now());
        blogRepository.save(blog);
        // Use the save method in the repository interface to save the entity.
        // Save entity sets value to field with @Id annotation.
        return "redirect: /blog/" +blog.getId();
    }

    @GetMapping("/blog/{id}")
    public String blog (@PathVariableIntegerid,Modelmodel) {
        Optional<Blog>blog=blogRepository.findById(id);
        // To make it easier to write when null, such as performing this action if the returned object is not null.
        Call the //get method to retrieve the contents.
        model.addAttribute("blog", blog.get());

        Comment comment = new Comment();
        comment.setBlog(blog.get());
        model.addAttribute("comment", comment);
        return "blog";
    }

    @ PostMapping ("/comment")
    public String createComment (Comment comment) {
        comment.setPostDateTime(LocalDateTime.now());
        commentRepository.save(comment);
        return "redirect: /blog /" + comment.getLog().getId();
    }

}

blog.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<metacharset="UTF-8">
<title:text="${blog.title}">Blog Title</title>
</head>
<body>
    <p>
        <a href="/"> Back to list </a>
    </p>
    <div th:object="${blog}">
            <h1th:text="*{title}">Title </h1>
        <div>
            Post Date and Time
            <spanth:text="*{postDateTime}">Post Date & Time</span>
        </div>
        <p>
            <th:blockth:each="line:*{contents.split('\n')}">
            <th:blockth:text="${line}">/th:block>br>
            </th:block>
        </p>

        <form action="/comment" method="post" th:object="${comment}">
                    Please read <br>
            <input type="hidden" name="blog"th:value="*{blog.id}">
            <input type="text" size="40" th:field="*{text}">
            <input type="submit">
        </form>

        <ul>
            <lith:each="c:*{comments}"th:object="${c}">
                <spanth:text="*{postDateTime}">/span>
                <spanth:text="*{text}">/span>
            </li>
        </ul>

    </div>
</body>
</html>

Error Contents

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Mon Jun 15 17:32:58 JST 2020
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object = 'comment'.Error count:1
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult:1 errors
Field error in object 'comment' on field 'blog': rejected value [4]; codes [typeMismatch.comment.blog,typeMismatch.blog,typeMismatch.com.example.demo.Blog,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [comment.blog,blog]; arguments []; default message [blog]]; default message [Failed to convert property value of type 'java.lang.String' to required type'com.example.demo.blog' for property'blog'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type'com.example.demo.blog' for property'blog'blog': no matching occurrence]

spring-boot jpa

2022-09-30 13:46

1 Answers

English SO also asked me the same question, which I was told would occur in Sprinb Boot 2.3.1.
If you are using a similar version, it may be the same cause, namely Bug on the framework side.

Originally, there is a converter ToEntityConverter that converts the ID of the JPA Entity into an Entity object, which should be utilized, but the bug does not register the converter and causes the error to occur./p>

The Spring Boot version is affected by 2.1.15, 2.2.8, 2.3.1, so avoid this version as a workaround.

Note:

Fixed in 2.3.2 and 2.4.0-M1, 2.2.9 released on 2020-07-24.

However, the 2.1 series has not been fixed at this time (2.1.16).

Note 2:

The other day (2020-11-01) Spring Boot 2.1 series received EOL, but it seems that The final version, 2.1.18, will not be fixed.


2022-09-30 13:46

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.