2016-08-17 2 views
2

Я разработал категории, подкатегории и объекты продукта для проекта JSF, и у меня возникла проблема с сопоставлением между SubCategory и Product с отношением ManytoMany. Ниже приведены категории, подкатегории и продукты ниже. Как я могу решить эту проблему? Thks.Использование @OneToMany или @ManyToMany для таргетинга на неподписанный класс (Категория, Подкатегория, Продукт)

@Entity 
    @Table(name="CATEGORY",schema="DEMO") 
    public class Category implements Serializable{ 

    @Id 
    @SequenceGenerator(name="catseq",sequenceName="seqCatSEQ",allocationSize=1) 
    @GeneratedValue(generator="catseq",strategy=GenerationType.SEQUENCE) 
    @Column(name="ID") 
    private Integer id; 

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

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


    @OneToMany(cascade = { CascadeType.PERSIST },mappedBy="category") 
    private Set<SubCategory> subcategories = new HashSet(); 

    public Category() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 


    public Category(String name, String catDesc) { 
     super(); 
     this.name = name; 
     this.catDesc = catDesc; 
    } 


    public Integer getId() { 
     return id; 
    } 

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

    public String getName() { 
     return name; 
    } 

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

    public String getCatDesc() { 
     return catDesc; 
    } 

    public void setCatDesc(String catDesc) { 
     this.catDesc = catDesc; 
    } 


    public Set<SubCategory> getSubcategories() { 
     return subcategories; 
    } 


    public void setSubcategories(Set<SubCategory> subcategories) { 
     this.subcategories = subcategories; 
    } 


} 

SubCategory:

package entities; 

import java.io.Serializable; 
import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToMany; 
import javax.persistence.ManyToOne; 
import javax.persistence.OneToMany; 
import javax.persistence.SequenceGenerator; 
import javax.persistence.Table; 


@Entity 
@Table(name="SUBCATEGORY",schema="DEMO") 
public class SubCategory implements Serializable{ 

    @Id 
    @SequenceGenerator(name="subcatseq",sequenceName="seqSubCatSEQ",allocationSize=1) 
    @GeneratedValue(generator="subcatseq",strategy=GenerationType.SEQUENCE) 
    @Column(name="ID") 
    private Integer id; 

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

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

    @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE}) 
    @JoinColumn(name = "CAT_ID") 
    private Category category; 

    @ManyToMany(cascade=CascadeType.PERSIST,mappedBy="subcategories") 
    Set<Product> products = new HashSet<Product>(); 


    public SubCategory() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 

    public SubCategory(String subName, String subNameDes) { 
     super(); 
     SubName = subName; 
     SubNameDes = subNameDes; 
    } 

    public Integer getId() { 
     return id; 
    } 

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

    public String getSubName() { 
     return SubName; 
    } 

    public void setSubName(String subName) { 
     SubName = subName; 
    } 

    public String getSubNameDes() { 
     return SubNameDes; 
    } 

    public void setSubNameDes(String subNameDes) { 
     SubNameDes = subNameDes; 
    } 


    public Category getCategory() { 
     return category; 
    } 

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



} 

продукт:

import java.io.Serializable; 
import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.ManyToMany; 
import javax.persistence.SequenceGenerator; 
import javax.persistence.Table; 

@Entity 
@Table(name="PRODUCTS",schema="DEMO") 
public class Product implements Serializable{ 

    @Id 
    @SequenceGenerator(name="proseq",sequenceName="proSEQ",allocationSize=1) 
    @GeneratedValue(generator="proseq",strategy=GenerationType.SEQUENCE) 
    @Column(name="ID") 
    private Integer id; 


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

    @Column(name="QUANTITY") 
    private Integer quantity; 

    @Column(name="PRICE") 
    private Double price; 

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


    @ManyToMany(cascade=CascadeType.ALL) 
    @JoinTable(name="PRODUCT_SUBCATEGORY", 
     joinColumns={@JoinColumn(name="PRODUCT_ID")}, 
     inverseJoinColumns={@JoinColumn(name="SUBCATEGORY_ID")} 
    ) 
    Set<SubCategory> subcategories = new HashSet<SubCategory>(); 


    public Product() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 


    public Product(String productName, Integer quantity, Double price, String productDes, 
      Set<SubCategory> subcategories) { 
     super(); 
     this.productName = productName; 
     this.quantity = quantity; 
     this.price = price; 
     this.productDes = productDes; 
     this.subcategories = subcategories; 
    } 


    public Integer getId() { 
     return id; 
    } 


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


    public String getProductName() { 
     return productName; 
    } 


    public void setProductName(String productName) { 
     this.productName = productName; 
    } 


    public Integer getQuantity() { 
     return quantity; 
    } 


    public void setQuantity(Integer quantity) { 
     this.quantity = quantity; 
    } 


    public Double getPrice() { 
     return price; 
    } 


    public void setPrice(Double price) { 
     this.price = price; 
    } 


    public String getProductDes() { 
     return productDes; 
    } 


    public void setProductDes(String productDes) { 
     this.productDes = productDes; 
    } 


    public Set<SubCategory> getSubcategories() { 
     return subcategories; 
    } 


    public void setSubcategories(Set<SubCategory> subcategories) { 
     this.subcategories = subcategories; 
    } 


} 
+0

Ваш 'компонент -scan' установлен в правильные пакеты? Является ли заявление пакета отсутствующим в скопированном коде или являются сущностями в разных пакетах? – Jens

+0

Для отношения многих ко многим мне хотелось бы удалить настройки 'CascadeType' в аннотации' @ ManyToMany'. 1. сохраняйте подкатегорию, 2. сохраняйте продукт. 3. установите отношения между подкатегориями и изменением сеанса работы и синхронизации в базу данных (если этот шаг не находится на одном и том же сеансе 1 и 2, вам может потребоваться слияние состояния подкатегории и продукта вручную) – Hantsy

ответ

1

Первый mappedby определяется как это относится к полю, которому принадлежит отношениям, С другого смыслом, отображаемым относится к классу таблицы который имеет внешний ключ

Итак, у нас есть два mappedBy, которые suspiecous позволяет принимать их один за другим:

1-

@OneToMany(cascade = { CascadeType.PERSIST },mappedBy="category") 
    private Set<SubCategory> subcategories = new HashSet(); 

Это означает, что subcategory стол и класс имеет поле отношения так subcategory таблица является тот, кто имеет внешний ключ и от SubCategory класса имя внешнего ключа - CAT_ID, так что это нормально.

2-

@ManyToMany(cascade=CascadeType.PERSIST,mappedBy="subcategories") 
Set<Product> products = new HashSet<Product>(); 

Хорошо это один показывает, что существует поле, называемое subcategories в Product классе это один владеет отношения БАМ это не верно, так как это ManyToMany владелец отношения должны быть третья таблица существует в базе данных и должна быть логически понята с помощью спящего режима

Так что это вопрос mappedBy относится к полю, который не является владельцем отношений, и поскольку владелец является некоей анонимной итй это должно быть так:

@ManyToMany(cascade=CascadeType.PERSIST) 
@JoinTable(name="PRODUCT_SUBCATEGORY", 
     joinColumns={@JoinColumn(name="SUBCATEGORY_ID")}, 
     inverseJoinColumns={@JoinColumn(name="PRODUCT_ID")} 
Set<Product> products = new HashSet<Product>(); 
  • Примечание Ваш PRODUCT_SUBCATEGORY таблица должна иметь только два первичных ключей и должны быть первичными, так что спящий режим понимает, что это ManyToMany отношения
Смежные вопросы

 Смежные вопросы