Search code examples
hibernatejpaspring-data-jpaone-to-manyhibernate-onetomany

Duplicate key in Hibernate JPA OneTOMany save operation


This is my Item class

@Entity
@Table(name = "item", schema = "demo_transaction")
@Transactional
public class Item {
    @Id
    Integer item_id;
    String itemName;
    Integer price;

    @OneToMany(cascade = CascadeType.ALL,fetch= FetchType.EAGER)
    List<Event> events;

Event class:

@Entity
@Table(name = "event", schema = "demo_transaction")
@Transactional
public class Event {
    @Id
    Integer event_id;
String eventName;

As shown Item can have multiple Events. In typical SQL an FK table would be like this:

item_id event_id
1       10
1       20
2       10 
2       20

But when I am trying to save these I am getting constrain violation.

    Event e1=new Event(10,"FirstEvent");
    Event e2=new Event(20,"SecondEvent");
List<Event> lse1=new ArrayList<>();
        lse1.add(e1);
        lse1.add(e2);
        Item item1 = new Item(1,"FirstItem",600,lse1);
List<Event> lse2=new ArrayList<>();
        lse1.add(e1);
        lse1.add(e2);
        Item item2 = new Item(2,"SecondItem",200,lse2);
repo.save(item1);repo.save(item2);

I understand that since eventId is the primary key and I am trying to save twice that's where the constraint getting violated but how would I achieve that FK table? Please help


Solution

  • What you are trying is not possible with a OneToMany configuration. An item can have many events, but an event can only have one item. You are trying to add the same event to multiple items.

    postgres=# \d item_events;
                     Table "public.item_events"
         Column      |  Type   | Collation | Nullable | Default 
    -----------------+---------+-----------+----------+---------
     item_item_id    | integer |           | not null | 
     events_event_id | integer |           | not null | 
    Indexes:
        "uk_nvp3wmby13pbecx8ikeoae9ep" UNIQUE CONSTRAINT, btree (events_event_id)
    Foreign-key constraints:
        "fk98kk1sdgqem8j50mo5avvvmg5" FOREIGN KEY (events_event_id) REFERENCES event(event_id)
        "fkovh11t671qjb2w11sxos7ktvo" FOREIGN KEY (item_item_id) REFERENCES item(item_id)
    

    As you can see the unidirectional OneToMany creates a join table, item_events, and the event_id column has a unique constraint on it to ensure an event can only belong to one item. Without this the relationship becomes a ManyToMany. If you want to add the same event to multiple items you will have to configure the ManyToMany relationship in your entities.