Spring Hibernate产品 - 类别关系

时间:2013-10-01 09:18:24

标签: java spring hibernate relationship

我已经阅读了许多关于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>

4 个答案:

答案 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;
.
.
.