【问题标题】:Field error trying to save object in Spring Boot & Hibernate尝试在 Spring Boot 和 Hibernate 中保存对象的字段错误
【发布时间】:2020-12-31 12:04:50
【问题描述】:

第一次使用 Spring Boot 和 Hibernate 制作项目,我遇到了一个错误,我不知道如何修复。尝试提交表单以创建新的纱线对象时发生错误。

相关控制器(HomeController.java):

@Controller
public class HomeController {
    @Autowired
    private BrandRepository brandRepository;

    @Autowired
    private ColorRepository colorRepository;

    @Autowired
    private WeightRepository weightRepository;

    @Autowired
    private YarnRepository yarnRepository;

    @RequestMapping("")
    public String index(Model model) {
        model.addAttribute("title", "My Yarns");

        return "index";
    }

    @GetMapping("yarn/add")
    public String displayAddYarnForm(Model model) {
        model.addAttribute("title", "Add Yarn");
        model.addAttribute(new Yarn());
        model.addAttribute("colors", colorRepository.findAll());
        model.addAttribute("brands", brandRepository.findAll());
        model.addAttribute("weights", weightRepository.findAll());

        return "yarn/add";
    }

    @PostMapping("yarn/add")
    public String processAddYarnForm(@ModelAttribute Yarn newYarn, Error errors,
                                     Model model,
                                     @RequestParam (required = false) Integer brand,
                                     @RequestParam (required = false) Integer color,
                                     @RequestParam (required = false) Integer weight) {

        model.addAttribute("newYarn", newYarn);
        Optional<Brand> yarnBrand = brandRepository.findById(brand);
        Optional<Color> yarnColor = colorRepository.findById(color);
        Optional <Weight> yarnWeight = weightRepository.findById(weight);
        yarnRepository.save(newYarn);
        return "redirect:";
    }
}

表格(add.html):

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head th:replace="fragments :: head">
    <meta charset="UTF-8">
</head>
<body>

<div th:replace="fragments :: page-header"></div>

<div class="container body-content">
<form method="post" style="max-width:600px;">

    <div class="form-group">
        <label th:for="name">Name</label>
        <input class="form-control" th:field="${yarn.name}" />
    </div>

    <div class="form-group">
        <label th:for="brand">Brand</label>
        <select th:field="${yarn.brand}">
            <option th:each="brand : ${brands}"
                    th:text="${brand.name}"
                    th:value="${brand.id}"></option>
        </select>
        <a th:href="@{'/brand/add'}">Add Brands</a>
    </div>

    <div class="form-group">
        <label th:for="color">Color</label>
        <select th:field="${yarn.color}">
            <option th:each="color : ${colors}"
                    th:text="${color.name}"
                    th:value="${color.id}"></option>
        </select>
        <a th:href="@{'/color/add'}">Add Colors</a>
    </div>

    <div class="form-group">
        <label th:for="weight">Weight</label>
        <select th:field="${yarn.weight}">
            <option th:each="weight : ${weights}"
                    th:text="${weight.name}"
                    th:value="${weight.id}"></option>
        </select>
    </div>

    <input type="submit" value="Add Yarn" />
</form>

</div>

</body>
</html>

Yarn 模型:

@Entity
public class Yarn extends AbstractEntity{

    @ManyToOne
    private Brand brand;

    @ManyToOne
    private Weight weight;

    @ManyToOne
    private Color color;

    public Yarn() {
    }

    public Yarn(Brand brand, Weight weight, Color color) {
        this.brand = brand;
        this.weight = weight;
        this.color = color;
    }

    public Brand getBrand() {
        return brand;
    }

    public void setBrand(Brand brand) {
        this.brand = brand;
    }

    public Weight getWeight() {
        return weight;
    }

    public void setWeight(Weight weight) {
        this.weight = weight;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

}

以及每个模型扩展的 AbstractEntity 类:

@MappedSuperclass
public abstract class AbstractEntity {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    public AbstractEntity() {

    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public AbstractEntity(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AbstractEntity that = (AbstractEntity) o;
        return id == that.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

(我也有颜色、重量、品牌的模型,但这些似乎是多余的) 和错误:

There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='yarn'. Error count: 3
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors
Field error in object 'yarn' on field 'brand': rejected value [1]; codes [typeMismatch.yarn.brand,typeMismatch.brand,typeMismatch.one.philosopherstone.knittingconversions.models.Brand,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [yarn.brand,brand]; arguments []; default message [brand]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'one.philosopherstone.knittingconversions.models.Brand' for property 'brand'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'one.philosopherstone.knittingconversions.models.Brand' for property 'brand': no matching editors or conversion strategy found]

我不确定为什么表单发送的类型不匹配,任何帮助将不胜感激。

【问题讨论】:

  • 好吧,看起来您正在尝试发送一个字符串(我认为它是 th:value="${brand.id}"),而不是作为您实体的一个字段的品牌本身。您应该找到一种将品牌对象从前端发送到后端的方法。我不使用 Thymeleaf,但我认为它不会那么复杂。
  • 这个错误什么时候出现?当您发布表单或获取表单时?​​span>
  • 我编辑了帖子,它在我提交表单时发生。把控制器的输入参数改成字符串,再转成整数,能解决问题吗?
  • 好吧,通常最好发送一个包含所有参数的对象。我没有在前端使用过百里香,但请查看stackoverflow.com/questions/17669212/…

标签: java mysql spring-boot hibernate


【解决方案1】:

问题似乎出在这个

th:value="${brand.id}"&gt;&lt;/option&gt; 在您的 HTML 页面中。

这里我们应该传递一个品牌而不是它的 id,只需按如下所示进行更改 您还必须在颜色和重量选择中进行更改。

th:value="${brand}"&gt;&lt;/option&gt;

【讨论】:

  • 如何更改控制器来处理品牌对象?目前我正在使用 brandRepository.findByID 在现有品牌对象中查找品牌。
  • 您将在使用 newYarn 对象获得的品牌对象中获得该 ID。
  • 可选 yarnBrand = brandRepository.findById(brand.getId());返回相同的错误。和 newYarn.setBrand(brand);
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2015-04-13
  • 2018-02-10
  • 2012-12-02
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多