2013-10-01 81 views
1

我读过很多教程关于弹簧休眠的关系,但我有点困惑如何在我的情况下使用它们......我的产品/类别实体定义如下:春天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; 
. 
. 
. 

所以,我LIK E在产品列表页面,根据语音“类别”将出现在类别名称,并在产品形成的类别列表... 在我来说,一个产品只适合一类,所以如果我是正确的应该是@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; 

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从产品形态串类别将数据转换......但现在,当我节省了产品它会自动保存一个类别,而不是附加当前选择之一......

回答

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; 
    } 

试试这个,如果不是我们可以看看另一种解决方案..

0

你似乎有类别和产品(一类具有许多产品)

在Java之间的一个一对多的关系(通常是OO),你会期望Category类包含一个Products列表,因此这个Category可以说是'拥有'的产品。

在SQL它是反过来 - 你所期望的产品表来保存的外键引用的范畴,所以在这里,产品可以以自己的“类别可说的。

看起来像使用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; 
} 
+0

太好了!这是我需要的缺失部分!顺便说一句,我有没有从产品数据库表中删除类别ID?还有......我还要更改类别db一个吗? –

+0

你不需要自己创建表格。 Hibernate可以为你做这件事 - 当你运行它时,模式是由注释(如果需要的话)生成的。除非您已经拥有需要保留的数据,否则我建议删除所有表格,运行代码,然后检查新创建的表格和FK约束,以查看它们是否与预期一致。 – NickJ

+0

我觉得如果我声明了auto.dll,hibernate会为我做这件事 –

0

你说得对,你应该使用@ ManyToOne,因为“...产品只适合一个类别......”。

在产品实体中声明一个类别字段而不是int类别,并使用@ManyToOne对其进行注释。还要添加@JoinColumn来指定数据库中的product.category_id列的名称。

产品

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column 
private int id; 


@ManyToOne 
@JoinColumn(name = "category_id") 
private Category category; 
. 
. 
. 
1

由于Product将只有一个类别,并Category都会有产品的列表,你可以通过在产品表创建一个Foreign Key指主要涉及这两个键在类别表中:

Category Table: id, name, other fields... 
Product Table: id, category_id (FK), and other fields. 

并且映射可以被定义如下:

​​

mappedBy属性告诉Hibernate集合是另一端多对一关联的镜像。它就像告诉Hibernate它应该将关联的Product末尾所做的更改传播到数据库,而忽略仅对Category中的products集合所做的更改。因此,如果我们只拨打category.getProducts().add(product),则不会进行任何更改。由于该关联是双向的,因此您必须创建双方的链接,而不仅仅是一个。

为了您的方便,你可以在Category类添加一个addProduct方法来保存协会:

public void addProduct(Product product) { 
     product.setCategory(this); 
     products.add(product); 
} 
+0

感谢您的帮助,我实现了您的版本,并且它似乎正常工作......现在我有另一个问题:在产品表单中,我选择带有“选项”框......我如何将它保存在产品数据库表category_id字段中? –

+0

如何在产品列表jsp页面中显示正确的类别名称? –

+0

创建产品:'产品p =新产品()',设置产品的价值。然后创建类别:'Category c = new Category()',设置类别的值并将产品'p'添加到该类别中:'c.addProduct(p)'。然后将类'c'传递给'session.save(c)'方法。这会将产品'p'与类别'c'一起保存。 –

相关问题