使用Thymeleaf发布具有多对一关系的数据 [英] POSTing data with many to one relationship using Thymeleaf

查看:89
本文介绍了使用Thymeleaf发布具有多对一关系的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的模型类 Product ,它与 ProductCategory 表现出多对一的关系:

I have a simple model class Product which exhibits a many to one relationship with ProductCategory:

产品类别:

@Entity
@Table(name="product")
public class Product {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id;

@Column(name="name")
private String name;

@Column(name="description")
private String description;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="category_id")
private ProductCategory category;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

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

public String getPdfUrl() {
    return pdfUrl;
}

public void setPdfUrl(String pdfUrl) {
    this.pdfUrl = pdfUrl;
}

public ProductCategory getCategory() {
    return category;
}

public void setCategoryId(ProductCategory category) {
    this.category = category;
}

}

ProductCategory类

@Entity
@Table(name="product_category",uniqueConstraints={@UniqueConstraint(columnNames="name")})
public class ProductCategory {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id;

@Column(name="name")
private String name;

@OneToMany(fetch=FetchType.LAZY, mappedBy="category")
private Set<Product> products = new HashSet<Product>(0);

// getters() & setters()

}

我将Thymeleaf与Spring boot结合使用,以创建通常的CRUD操作所需的表格.

I am using Spring boot with Thymeleaf to create the necessary forms for the usual CRUD operations.

这是我的html页面的基本部分,可用于在数据库中添加新的 Product 对象.

Here is the essential portion of my html page which I use to add a new Product object into the database.

<form action="#" th:action="/product/save" th:object="${newProduct}" method="POST">
  <input type="text" th:field="*{name}" />
  <input type="text" th:field="*{description}" />
  <select th:field="*{category}">
    <option th:each="category: ${productCategories}" th:value="${category}" th:text="${category.name}" />
  </select>
  <button type="submit">Submit</button>
</form>

问题是,当我尝试从控制器中插入生成的 Product 对象时(我知道我没有在此处显示它,主要是因为我认为这实际上不是问题),有一个

The problem is, when I try and insert the resulting Product object from the controller (I know I haven't shown it here, mostly because I don't think that is actually the cause of the problem), there is a

MySQLIntegrityConstraintViolationException: Column 'category_id' cannot be null

我尝试将 option value 更改为 $ {category.id} ,但是即使这样也无法解决.

I have tried changing the value of the option to ${category.id}, but even that doesn't fix it.

实际上如何使用Thymeleaf将复杂的对象作为POST参数传递给控制器​​?

How do I actually pass a complex object as a POST parameter into a controller using Thymeleaf?

与我最初的想法相反,这实际上可能与我的 Controller 有关,所以这是我的 ProductController :

Contrary to my first thoughts, this might actually be related to my Controller, so here is my ProductController:

@RequestMapping(value="/product/save", method=RequestMethod.POST)
public String saveProduct(@Valid @ModelAttribute("newProduct") Product product, ModelMap model) {
    productRepo.save(product);
    model.addAttribute("productCategories", productCategoryRepo.findAll());
    return "admin-home";
}

@RequestMapping(value="/product/save")
public String addProduct(ModelMap model) {
    model.addAttribute("newProduct", new Product());
    model.addAttribute("productCategories", productCategoryRepo.findAll());
    return "add-product";
}

推荐答案

请注意,我已将表单方法更改为POST.

从百里香的角度来看,我可以确保以下代码可以正常工作.

From thymeleafs perspective I can assure the below code should work.

<form method="POST" th:action="@{/product/save}" th:object="${newProduct}">
    ....
    <select th:field="*{category}" class="form-control">
       <option th:each="category: ${productCategories}" th:value="${category.id}" th:text="${category.name}"></option>
    </select>

提供您的控制器如下所示.

Provided that your controller looks like this.

@RequestMapping(value = "/product/save")
public String create(Model model) {
    model.addAttribute("productCategories", productCategoryService.findAll());
    model.addAttribute("newproduct", new Product()); //or try to fetch an existing object
    return '<your view path>';
}

@RequestMapping(value = "/product/save", method = RequestMethod.POST)
public String create(Model model, @Valid @ModelAttribute("newProduct") Product newProduct, BindingResult result) {
    if(result.hasErrors()){
        //error handling  
        ....
    }else {
        //or calling the repository to save the newProduct
        productService.save(newProduct);
        ....
    }
}

更新

您的模型应具有正确的吸气剂和吸气剂,并带有正确的名称.例如,对于属性 category ,您应该拥有

Your models should have proper getters and setters with the correct names. For example, for the property category You should have,

public ProductCategory getCategory(){
    return category;
}

public void setCategory(productCategory category){
    this.category = category;
}

注意-我尚未编译此代码,我从当前的工作项目中提取了该代码,并将其名称替换为您的班级名称

这篇关于使用Thymeleaf发布具有多对一关系的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆