New with Hibernate, I'm trying to achieve a very simple task but ending up round in circles with number of erros.
Two tables Cart
and Items
with One-To-Many relation. I want to call save on the parent table entity and expect child table to get saved as well.
Script 1:
CREATE TABLE cart
(
cart_id INTEGER NOT NULL,
reference_number INTEGER,
PRIMARY KEY (cart_id)
);
CREATE TABLE item
(
item_id INTEGER NOT NULL,
cart_id INTEGER NOT NULL,
name Varchar(255) ,
description Varchar(255) ,
PRIMARY KEY (item_id),
FOREIGN KEY (cart_id) REFERENCES cart
);
Using hibernate code generation following are the Entity classes.
@Entity
@Table(name = "CART", schema = "MYSCHEMA")
public class Cart implements java.io.Serializable {
private int cartId;
private Integer referenceNumber;
private List<Item> items = new ArrayList<Item>();
@Id
@Column(name = "CART_ID", unique = true, nullable = false)
public int getCartId() {
return this.cartId;
}
@OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true)
public List<Item> getItems() {
return items;
}
public void addItem(Item item) {
items.add(item);
item.setCart(this);
}
public void removeComment(Item item) {
items.remove(item);
item.setCart(this);
}
public void setItems(List<Item> items) {
this.items = items;
}
// Excluding rest of the Getters and Setterss
}
@Entity
@Table(name = "ITEM", schema = "MYSCHEMA")
public class Item implements java.io.Serializable {
private int itemId;
private int cartId;
private String name;
private String description;
private Cart cart;
@Id
@Column(name = "ITEM_ID", unique = true, nullable = false)
public int getItemId() {
return this.itemId;
}
@ManyToOne
@JoinColumn(name = "cart_id", nullable = false, insertable = false, updatable = false)
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
cart = cart;
}
// Excluding rest of the Getters and Setterss
}
With this setting when run following.
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Cart cart = new Cart();
cart.setReferenceNumber(333);
Item item1 = new Item();
item1.setName("itemONe");
item1.setDescription("itemOneDescription");
item1.setCart(cart);
cart.addItem(item1);
Item item2 = new Item();
item2.setName("itemONe");
item2.setDescription("itemOneDescription");
item2.setCart(cart);
cart.addItem(item2);
session.save(cart);
session.getTransaction().commit();
It gives following error .
Exception in thread "main" org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.testHibernate.models.Item#0]
Which makes sence as neither Hibernate nor Database is handling the auto generation of Primary key. So, If I run the above code with with Item1
only it works and saves both records.
For Generating ID via Database if I change my DB to following
Script 2:
CREATE TABLE cart
(
cart_id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
reference_number INTEGER,
PRIMARY KEY (cart_id)
);
CREATE TABLE item
(
item_id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
cart_id INTEGER NOT NULL,
name Varchar(255) ,
description Varchar(255) ,
PRIMARY KEY (item_id),
FOREIGN KEY (cart_id) REFERENCES cart
);
Keeping the Entity classes same as shown above, it has no effect. Same Error comes up.
I tried using the @GeneratedValue(strategy = GenerationType.IDENTITY)
with the PrimeryKey fields in both classes and the following error shows up on save.
ERROR: INSERT on table 'ITEM' caused a violation of foreign key constraint 'SQL0000000002-06ba0cd1-016e-2cf2-dad9-ffff908894b5' for key (0). The statement has been rolled back.
Isn't Hibernate supposed to handle this with cascade = CascadeType.ALL
?
What am i missing ?
Hibernate v5.4.4 Derby DB v10.15.1.3
In the first case you have 2 item entities with the same ID - zero.
For the 2nd error, how do you expect the non nullable foreign key column cart_id
to be set when you have defined the join column as insertable = false, updatable = false
? Remove these attributes and it should work.