as the question says. I have two tables Products and categories.
Product table
...
create table products (
id int primary key generated always as identity(start with 100, increment by 1),
name varchar(30),
quantity int,
unit_cost decimal not null,
brand_name varchar(30)
)
...
Categories table
...
create table categories
(
name varchar(30) primary key,
description varchar(30),
date_created date,
)
... the relationship they have is many to many relationship, so i created a relationship table.
Relationship table
...
create table product_categories
(
product_id int not null,
category_name varchar(30) not null
)
alter table product_categories add constraint product_categoriesFK foreign key (product_id)
references products (id)
alter table product_categories add constraint category_productsFK foreign key (category_name)
references categories (name)
These are there respective entity class.
Product Entity
@Entity
@Table(name = "PRODUCTS")
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Size(max = 255)
@Column(name = "NAME")
private String name;
@Column(name = "QUANTITY")
private Integer quantity;
@Column(name = "UNIT_COST")
private Integer unitCost;
@JoinTable(name = "REQUISITION_PRODUCTS", joinColumns = {
@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID")}, inverseJoinColumns = {
@JoinColumn(name = "REQUISITION_ID", referencedColumnName = "ID")})
@ManyToMany
private Collection<Requisition> requisitionCollection;
@ManyToMany(mappedBy = "productCollection", cascade = CascadeType.ALL)
private Collection<Category> categoryCollection;
@JoinColumn(name = "BRAND_NAME", referencedColumnName = "NAME")
@ManyToOne
private Brand brand;
@JoinColumn(name = "DEAL_ID", referencedColumnName = "ID")
@ManyToOne
private Deal dealId;
@OneToMany(mappedBy = "product")
private Collection<Feature> featureCollection;
...
Category Entity
@Entity
@Table(name = "CATEGORIES")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "NAME")
private String name;
@Column(name = "DATE_CREATED")
@Temporal(TemporalType.DATE)
private LocalDate dateCreated;
@Size(max = 255)
@Column(name = "DESCRIPTION")
private String description;
@JoinTable(name = "PRODUCT_CATEGORIES", joinColumns = {
@JoinColumn(name = "CATEGORY_NAME", referencedColumnName = "NAME")}, inverseJoinColumns = {
@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID")})
@ManyToMany
private Collection<Product> productCollection;
...
These entity classes were generated using netbeans ide. The relationship a table for the entity wasn't created, so i don't know how to insert/update the Categories a Product belongs to.
This is my code to that performs the insert/update.
@Override
public int update(Object value, Product t) {
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaUpdate<Product> cu = cb.createCriteriaUpdate(Product.class);
cu.set(Product_.brand, t.getBrand());
cu.set(Product_.id, t.getId());
cu.set(Product_.name, t.getName());
cu.set(Product_.quantity, t.getQuantity());
cu.set(Product_.unitCost, t.getUnitCost());
// cu.set(Product_.categoryCollection, t.getCategoryCollection());
Root<Product> root = cu.getRoot();
Predicate tester = cb.equal(root.get(Product_.id), value);
cu.where(tester);
Query q = getEntityManager().createQuery(cu);
return q.executeUpdate();
}
Product Metamodel class
...
public class Product_ {
public static volatile SingularAttribute<Product, Integer> quantity;
public static volatile CollectionAttribute<Product, Requisition> requisitionCollection;
public static volatile CollectionAttribute<Product, Category> categoryCollection;
public static volatile SingularAttribute<Product, Deal> dealId;
public static volatile SingularAttribute<Product, Integer> unitCost;
public static volatile SingularAttribute<Product, String> name;
public static volatile CollectionAttribute<Product, Feature> featureCollection;
public static volatile SingularAttribute<Product, Integer> id;
public static volatile SingularAttribute<Product, Brand> brand;
...
From what i can see, the metamodel class expects a category and not a collection of categories. Please can someone tell me how to solve this.
software
netbeans 8.0.2
glassfish server 4.1
jdk1.8.0_40
You should not use CriteriaUpdate
for a simple update by id when you have the whole record. Simply use
getEntiyManager().merge(t);