'Problem when persisting entities that have @OneToMany relations

I have to create a simple application with Spring and Postgres. I have some entities that are in relations, such is Job, Company, ProgrammingLanguage. A Job entity has a @ManyToOne relation with Company, and a @OneToMany relation with ProgrammingLanguage. I need to persist a lost of each of these 3 entities in the corresponding tables in DB, especially Job. After I create the objects Company and ProgrammingLanguage I persist them into DB using their repositories and everything is fine. Then I set these objects as attributes of the Job entity and persist that too. I run my application and for the first and second job from the list I must persist everything works fine, they are added to the DB. But when it comes to the third job the application crashes with an error that says:

2022-02-24 13:56:00.838  WARN 8364 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 23505

2022-02-24 13:56:00.839 ERROR 8364 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: duplicate key value violates unique constraint "uk_gi5d5wf8tux7hmiwtk9nhql9k"

Detail: Key (programming_languages_id)=(30) already exists.

Also I have the debugger on and print details about each ProgrammingLanguage, and each time the application stops at that id=30 of the ProgrammingLanguage record. This is the image with Output console from Netbeans

And the piece of code for creating and persisting entities is this:

Has anyone idea where does this duplicate id comes from in ProgrammingLanguage entity? Isn't it supposed to be a sequence that deals with entities' Ids?



Solution 1:[1]

I believe, your problem is that a programming language entity exists twice with ID 30 in your DB, isn't it?

Solution 2:[2]

You need to study a bit on persistence and understand how it works. Entities that are related together need to be persisted carefully. As a hint for your problem - You should save the top most entity only and that will save all related children entities. The error you are getting is because the programming language entity has alrady been saved (you saved it manually), and it is also being saved as part of the parent entity (as part of your third job)

Solution 3:[3]

I managed to find out the root of the problem that causes the effects I described. It is due to a constraint that is made by Spring when it creates the link table between Job and ProgrammingLanguage in which are stored the IDs of the 2 records, table that is called Job_Programming_Language in Postgres database. This constraint has the following code:

-- Constraint: uk_gi5d5wf8tux7hmiwtk9nhql9k

-- ALTER TABLE IF EXISTS public.job_entity_programming_languages DROP CONSTRAINT IF EXISTS uk_gi5d5wf8tux7hmiwtk9nhql9k;

ALTER TABLE IF EXISTS public.job_entity_programming_languages
ADD CONSTRAINT uk_gi5d5wf8tux7hmiwtk9nhql9k UNIQUE (programming_languages_id);

My question is now how do I get rid of this constraint, which imposes that stupid thing of unicity on ProgrammingLanguage Ids on that join created table? Or how do i alter it?

Solution 4:[4]

I found the answer alone. The relation between Job and ProgrammingLanguage , as it is stated in the Job entity , is not @OneToMany but @ManyToMany. If I annotate it like that the application does not crash anymore and it works perfectly because Hibernate does not create that constraint of uniqueness on the id of programming_language, as it does in the first case. Even though this is a mistake, in my opinion (since PrgrammingLanguage is a attribute of type List in Job entity), it makes the application works. The best reasonable solution would be to be able to delete that unique constraint that Hibernate creates, or impede its creation. But unfortunately I have only a 3 months experience with the Spring framework and i don't know hot to do that...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SaWo
Solution 2 vivek
Solution 3 andreiZam
Solution 4 andreiZam