Yegor Saliev
Yegor Saliev

Reputation: 125

jpa entity mapping couple tables

I had entity for JSON parsing

    @Entity
    public class Product{
    private int productId;
    private String productName;
    private BigDecimal productPrice;
    private int productVendorId;
    private String productVendorName;
    private int productCategoryId;
    private String productCategoryName;
    //getters setters here

created 3 tables in dataBase: products (product_id, product_name,product_price, product_vendor_id), product_category_id); vendors(vendor_id, vendor_name); categories (category_id, category_name); in 1st table product_vendor_id fk -> vendor_id pk in vendors and product_category_id fk -> category_id pk in categories i tried something like this:

    @Entity
    @Table(name = "products, schema = "market")
    public class Product
    @Id
    @Column(updatable = false, nullable = false, name = "product_id")
    private int Id;
    @Column(name = "product_name")
    private String productName;
    @Column(name = "product_price")
    private BigDecimal productPrice;
    @Column(name = "product_vendor_id")
    private int productVendorId;
    @Columnt(table = "vendors", name = "vendor_name")
    private String vendor_name;
    @Column(name = "product_category_id")
    private int productCategoryId;
    @Column(table = "categories", name = "category_name")
    private String productCategorName;
    //getters setters here

received alot of errors: like i have not category_name column in products table etc. this error i received when used

     @Table(name = "products", schema = "market" )
     @SecondaryTables({@SecondaryTable(name = "vendors", schema = "market"),
     @SecondaryTable(name = "categories", schema = "market")})
     @JsonIgnoreProperties(ignoreUnknown = true)
     public class Product {
     ....
     @JoinColumn(name = "product_vendor_id", referencedColumnName = "vendor_id")
     private int productVendorID;
     @JoinColumn(table = "vendors", name = "vendor_name")
     private String productVendorName;
     @JoinColumn(name = "product_category_id", referencedColumnName = 
     "product_category_id")
     private int productCategoryID;
     @JoinColumn(table = "categories",  name = "category_name")
     private String productCategoryName;    

exception:

     Caused by: org.postgresql.util.PSQLException: ERROR: column 
     product0_1_.product_id doesn't exist
     Hint: There may have been a link to the "product0_.product_id" column
     Position: 705     

how can i map this entity on 3 tables? upd: i don't want separate this entity, i need this for deserialize my json object too, just want reuse this entity on different operations. example of json

   {"productID":"1111111","productName":"Cool product","productPrice":"99.99","productVendorName":"Some store","productVendorID":"1337","productCategoryName":"Food","productCategoryID":"1"}

Upvotes: 0

Views: 375

Answers (2)

Yegor Saliev
Yegor Saliev

Reputation: 125

Sorry for poor wording of the question, just didn't know how to explane what i wanted. All what i need just add @transient annotations for fields which i don't have in products table, and separate it like accepted answer was suggested.

@Entity
@Table(name = "products", schema = "store" )
@JsonIgnoreProperties(ignoreUnknown = true)
public class Product {
@Id
@Column(updatable = false, nullable = false, name = "product_id")
private int productId;
@Column(name = "product_name")
private String productName;
@Column(name = "product_price")
private BigDecimal productPrice;
@Transient
private String productVendorName;
@Transient
private String productCategoryName;
@Transient
private int vendorId;
@Transient
private int categoryId;
@ManyToOne
@JoinColumn(name = "product_category_id")
private Category category;
@ManyToOne
@JoinColumn(name = "product_vendor_id")
private Vendor vendor;
}

for vendors table entity

@Entity
@Table(name = "vendors", schema = "store")
public class Vendor {
@Id
@Column(name = "vendor_id")
private int vendorId;
@Column(name = "vendor_name")
private String vendorName;
@OneToMany(mappedBy = "vendor", cascade = CascadeType.ALL, fetch = FetchType.LAZY, 
orphanRemoval = true)
@NotNull
private List<Product> products = new ArrayList<>();
}

and for categories

@Entity
@Table(name = "categories", schema = "store")
public class Category {
@Id
@Column(name = "category_id")
private Integer categoryId;
@Column(name = "category_name")
private String categoryName;
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, fetch = FetchType.LAZY, 
orphanRemoval = true)
@NotNull
private List<Product> products = new ArrayList<>();
}

Wanted to leave here full answer on my question, maybe someone will need it later Just check some problems with toString. Use it only in Product.class and better make 2 versions for print json and jpa.

Upvotes: 0

Aditya Narayan Dixit
Aditya Narayan Dixit

Reputation: 2119

Since there are 3 separate tables, you would want to create three separate entity classes. Also I'm assuming vendors and category tables will have one to many relation to product. Try below code:

Product:

@Entity
public class Product {
  @Id
  private int productId;
  private String productName;
  private BigDecimal productPrice;
  private String productVendorName;
  private String productCategoryName;
  @ManyToOne
  @JoinColumn(name = "productCategoryId")
  private Category category;
  @ManyToOne
  @JoinColumn(name = "productVendorId")
  private Vendors vendor;
}

Category:

@Entity
public class Category {
  @Id
  private Integer categoryId;
  private String categoryName;
  @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @NotEmpty
  private List<Product> products = new ArrayList<>();
}

Vendors:

@Entity
public class Vendors {
  @Id
  private int vendorId;
  private String vendorName;
  @OneToMany(mappedBy = "vendor", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @NotEmpty
  private List<Product> products = new ArrayList<>();
}

Though, I would recommend using above approach, if you still want to have single entity class and 3 separate table with redudant data then use below:

@Entity
@SecondaryTables({ @SecondaryTable(name = "vendors"), @SecondaryTable(name = "categories") })
public class Product {
  @Id
  private int productId;
  private String productName;
  private BigDecimal productPrice;
  private String productVendorName;
  private String productCategoryName;
  @Column(table = "categories")
  private Integer categoryId;
  @Column(table = "categories")
  private String categoryName;
  @Column(table = "vendors")
  private int vendorId;
  @Column(table = "vendors")
  private String vendorName;
}

The id column of the main table will be present in all the 3 tables and used for joining them.

Upvotes: 1

Related Questions