我已经阅读了许多关于spring-hibernate关系的教程,但我对如何在我的情况下使用它们感到有点困惑......我的产品/类别实体定义如下:
产品
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int id;
@Column
private int category;
.
.
.
分类
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int id;
@NotEmpty
@Column
@Size (max = 25)
private String name;
.
.
.
所以,我想在产品列表页面中,语音“类别”下面会出现类别名称,而在产品表单中会出现类别列表... 在我的情况下,产品只适合一个类别,所以如果我是对的,它应该是@ManyToOne但我不知道如何实现这个...在我的产品数据库中我有categoryId字段,但如果我标记类别实体字段为@OneToMany,它不会存储到db ...
修改 我改变了这样(如建议的那样): 的 Product.class
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int id;
@NotEmpty
@Column
@Size (max = 25)
private String name;
@Column
@Size (max = 255)
private String description;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "category_id", nullable = false)
private Category category;
Category.class
@Entity
@Table(name = "categories")
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int id;
@NotEmpty
@Column
@Size (max = 25)
private String name;
@Column
@Size (max = 255)
private String description;
//Here mappedBy indicates that the owner is in the other side
@OneToMany(fetch = FetchType.EAGER, mappedBy = "category", cascade = CascadeType.ALL)
private Set<Product> products = new HashSet<Product>();
控制器
@RequestMapping(value = "/add/", method = RequestMethod.POST)
public String addProduct(
@ModelAttribute(value = "product") @Valid Product product,
BindingResult result, ModelMap model, Category category) {
if (result.hasErrors()) {
return "forms/productForm";
}
try {
category.addProduct(product);
product.setCategory(category);
// Add product to db
productService.addProduct(product);
} catch (Exception e) {
log.error("/add/---" + e);
return "redirect:/product/deniedAction/?code=0";
}
return "redirect:/admin/product/";
}
我还在产品控制器上添加了一个@initbinder,用于将数据从产品表单字符串转换为类别...但是现在当我保存产品时,它会自动保存一个类别,而不是附加现有的一个...... < / p>
答案 0 :(得分:1)
由于Product
只有一个类别而Category
会有一个产品列表,您可以通过在Product表中创建Foreign Key
来引用这两个产品来关联这两个产品。类别表中的键:
Category Table: id, name, other fields...
Product Table: id, category_id (FK), and other fields.
映射可以定义如下:
public class Category {
//Here mappedBy indicates that the owner is in the other side
@OneToMany(fetch = FetchType.LAZY, mappedBy = "category", cascade = CascadeType.ALL)
private Set<Product> products = new HashSet<Product>();
...
}
public class Product {
//Here JoinColumn states that this entity is the owner of the relationship
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id", nullable = false)
private Category category;
...
}
mappedBy
属性告诉Hibernate该集合是另一侧多对一关联的镜像。它告诉Hibernate它应该将关联的Product
末端所做的更改传播到数据库,而忽略仅对products
中的Category
集合所做的更改。因此,如果我们只调用category.getProducts().add(product)
,则不会进行任何更改。由于关联是双向的,您必须在两侧创建链接,而不仅仅是一个。
为方便起见,您可以在addProduct
课程中添加一个Category
方法来保存关联:
public void addProduct(Product product) {
product.setCategory(this);
products.add(product);
}
答案 1 :(得分:0)
所以你有这个:
Product{
atributtes...
@ManyToOne
Category category; --so every product has a category
}
Category {
attributtes...
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="id_Product")
private List<Product> products;
}
尝试这个,如果不是,我们可以寻找另一种解决方案..
答案 2 :(得分:0)
您似乎在类别和产品之间存在一对多关系(一个类别包含许多产品)
在Java(通常是OO)中,您希望Category类包含Products列表,因此Category可以说是“拥有”产品。
在SQL中,它反过来了 - 你希望Product表持有一个Category的外键引用,所以在这里,Product可以说是“拥有”一个Category。
看起来你正在使用JPA,所以你可以这样:
分类:
@Entity
public class Category {
//other stuff...
@OneToMany(cascade=CascadeType.ALL, mappedBy="category")
private Set<Product> products;
}
产品类别:
@Entity
public class Product {
//other stuff...
@ManyToOne
private Category category;
}
答案 3 :(得分:0)
你是对的,你应该使用@ManyToOne因为“......产品只适合一个类别......”。
在Product实体中声明一个Category字段而不是int category,并使用@ManyToOne注释它。另外,添加@JoinColumn以指定数据库中product.category_id列的名称。
<强>产品强>:
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private int id;
@ManyToOne
@JoinColumn(name = "category_id")
private Category category;
.
.
.