4

我已经阅读了许多关于 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,它将不会存储到数据库中。 ..

编辑 我已经改变了(如建议的那样): 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;

类别.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,以将数据从产品表单字符串转换为类别...但是现在当我保存产品时,它会自动保存一个类别而不是附加现有的选定类别...

4

4 回答 4

4

由于Product只有一个 Category 并且Category会有一个 Products 列表,因此您可以通过Foreign Key在 Product 表中创建一个来引用 Category 表中的主键来关联这两者:

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);
}
于 2013-10-01T10:40:06.137 回答
1

您似乎在 Category 和 Product 之间存在一对多的关系(一个类别有很多产品)

在 Java(和一般的 OO)中,您希望 Category 类包含产品列表,因此可以说 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;
}
于 2013-10-01T09:56:10.627 回答
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;
    }

试试这个,如果没有,我们可以看看另一个解决方案..

于 2013-10-01T09:55:57.130 回答
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;
.
.
.
于 2013-10-01T09:57:22.917 回答