JPA Repository.save with Unique Key constraints - java

I am using JPA to make an insert into my POSTGRES db. I recently added a Unique key constraint on one of the tables. The table looks like this:
______________________________________________
|Id| Action| Actor| Assignee| Date| Team|
----------------------------------------------
Id is the primary Key and the combination of Action, Actor, Assignee and Date is an unique key. When I get the JSON object from the 3rd party API i use the following method to save the data into the database.
streamItemArray.parallelStream().forEach(streamItem -> {
try{
streamItemRepository.save(streamItem);
}catch(ConstraintViolationException e){
System.out.println("Issue with unique key");
System.out.println(e.getMessage());
}
catch (Exception e){
System.out.println("others");
System.out.println(e.getMessage());
}
});
the code ran for the first few time and now it is not running at all.
2017-07-31 15:14:04.811 WARN 7867 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23505
2017-07-31 15:14:04.812 ERROR 7867 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: duplicate key value violates unique constraint "Unique_key"
Detail: Key (action, actor, assignee, date)=(Dismissed, Karen William, Karen William, 2017-07-21 01:19:05 IST) already exists.
2017-07-31 15:14:04.812 INFO 7867 --- [nio-8080-exec-4] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
others
could not execute statement; SQL [n/a]; constraint [Unique_key]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
My question here is:
How do we handle duplicates when we insert into db using JPA?
When using the foreach statement, if one repository.save fails will it execute the next item in foreach or does it stop the complete execution there itself?
Thanks for your help in advance.

Related

Hibernate-Entity Not found exception -Spring batch

I have #manytoone relationship from person table to country table on country-id (foreign key)
In country table -id 's started from 1.
However while saving data in person table .
I'm getting an error
EntityNotFound:unable to find country id 0
Also ,there is an error
HHH000100: Fail-safe cleanup (collections) : org. hibernate. engine. loading. internal. CollectionLoadContext#5da03062<rs-
HikariPro onLoadContext -
HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries
What will be the possible causes of this.
This error occurred in spring batch application
1.checked table data --there is no entry in country table with id 0
You probably did not set countryId = 1, on the new person object which you are trying to persist

Finding the name of the column in which duplicate value was inserted

In hibernate for columns annotated with #Column(unique = true) we get an exception when trying to insert a duplicate value for that column.
2022-07-31 19:47:18.112 ERROR 14372 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : Duplicate entry ' someValue' for key 'business.UK_3h6o7iww8015m4q3yffbkqtrw'
So from the above log, I know that business is the table in which I am inputting a duplicate value.
Is there a way to know in which column the duplicate value is getting inserted into? Since a single table can have multiple unique columns.
In addition to what Davide D'Alto wrote, you can also enable SQL logging, e. g. as shown here.
You can check the SQL for the table creation:
show create table business;
or you can run the following query:
select COLUMN_NAME
from information_schema.KEY_COLUMN_USAGE
where TABLE_NAME = 'business' and CONSTRAINT_NAME='UK_3h6o7iww8015m4q3yffbkqtrw'

Hibernate is throwing managed flush exception

We are trying to save entity in Oracle : Oracle Database 11g Enterprise Edition Release 11.2.0.3.0
We are using Hibernate for same:
We are getting following distinct error:
o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
Detailed relevant stacktrace is as below:
[ERROR]--- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-00001: unique constraint (XXX.PK_USER_FAVORITE) violated
[WARN ] --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1, SQLState: 23000
[ERROR] --- [nio-8080-exec-9] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [**org.hibernate.exception.ConstraintViolationException**: could not execute statement]
[ERROR] --- [nio-8080-exec-9] c.mastercard.refarch.aop.ServiceLogging : {"aop_service":"UserFavoritesService", "method":"addCurrentUserFavorite", "type":"failed", "error":"could not execute statement; SQL [n/a]; constraint [XXX.PK_USER_FAVORITE]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement", "args":"(["s029158",{"userFavoriteId":null,"applicationId":"XXX","functionAlphaCode":"SOME vale","title":"Service Report"}])"}
We are using oracle sequence for generating primary key value. I guess we are getting above issue when oracle sequence is trying to execute. Hibernate is failing to execute Oracle sequence whenever we get above exception, Thats main smell here.
There is also not null and primary key constraint on Entity that we are trying to save on DB.
Current Hibernate Version is Hibernate-core 5.2.17
and version if hibernate JPA is Hibernate-JPA-2.1-API-1.0.2.Final
Still wondering why we are getting :
Error during managed flush [org.hibernate.exception.ConstraintViolationException:
The important part is the error message which says ORA-00001: unique constraint (XXX.PK_USER_FAVORITE) violated. Apparently the unique constraint on your USER_FAVORITE table is being violated.
Check the sequence to see what its next value is, then check to see what the maximum value of this unique key column in the USER_FAVORITE table is. If the max value of the unique column is >= the next value from the sequence you'll have to fix things up.

Hibernate : Why is it trying to drop/create database on startup?

I'm new with Spring. I finally succeeded to build my application with no error but when i'm looking to the output i have a lot of information that i don't understand.
First this error each tables, it seems to be a Hibernate/Spring bug :
Hibernate: alter table entity.administrationaction drop constraint FKjaafjywumaavhae5kjyo34gx5
2016-11-13 12:16:41.475 ERROR 2156 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: alter table entity.administrationaction drop constraint FKjaafjywumaavhae5kjyo34gx5
2016-11-13 12:16:41.475 ERROR 2156 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : ERREUR: la relation « entity.administrationaction » n'existe pas
Then this for each table :
Hibernate: drop table if exists entity.administrationaction cascade
Then this for each table :
Hibernate: create table entity.administrationaction (id serial not null, action int4, creation_date timestamp, entity_class varchar(255), entity_id int4, message varchar(255), administrator_id int4, primary key (id))
So it is like Spring was trying to drop all my database and recreate it. Why ? Is it normal or have i done something wrong ?
Place in application.properties/application.yml
spring.jpa.hibernate.ddl-auto=update
This property can be set with values
1. update (Update the schema if necessary)
2. create (create the schema and destroy previous data)
3. create-drop (create and then destroy the schema at the end of the session)
4. none (disable ddl handling)
5. validate (validate the schema , make no changes to the database)
Look for the hibernate.hbm2ddl.auto setting. Probably you have set it to create-drop.
Some additional information as I found myself here not understanding why Spring would default to create-drop:
spring.jpa.hibernate.ddl-auto String:
DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Defaults to "create-drop" when using an embedded database and no schema manager was detected. Otherwise, defaults to "none".
Source: Javadoc
spring.jpa.hibernate.ddl-auto=none
this worked for me and it didn't messed up with the table and just used it.
spring.jpa.hibernate.ddl-auto=validate
add this line in applications.properties file. This worked for me.

Hibernate - table doesn't exist during deletion

So I am trying to delete a hibernate entity from the database but it's giving me back an error saying the table doesn't exist. It doesn't seem to have any problem finding the entity and saving changes or creating new entities - it only complains when deleting an entity.
This code results in an error saying the table doesn't exist.
try
{
Transaction txn = s.beginTransaction();
Resource r = (Resource) s.get(Resource.class, rid);
s.delete(r);
txn.commit();
}
This code pulls the entity out of the database and prints the ID with no problems.
try
{
Transaction txn = s.beginTransaction();
Resource r = (Resource) s.get(Resource.class, rid);
System.out.println(r.getId());
txn.commit();
}
Console output
Hibernate:
select
resource0_.id as id1_1_0_,
resource0_.bookable as bookable2_1_0_,
resource0_.description as descript3_1_0_,
resource0_.name as name4_1_0_
from
resources resource0_
where
resource0_.id=?
Hibernate:
delete
from
resources_resources
where
resources_id=?
2016-02-07 02:27:13.831 WARN 8396 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1146, SQLState: 42S02
2016-02-07 02:27:13.831 ERROR 8396 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Table 'bargaink_megtest.resources_resources' doesn't exist
2016-02-07 02:27:13.831 INFO 8396 --- [nio-8080-exec-8] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
I have no idea how this could happen when it can quite clearly see the table when adding new entities and updating existing entities. Can anyone explain what is going on here?
Thanks
One possible explanation is that maybe you would be that your hibernate.hbm2ddl.auto is set to create. If it's so, then please change it.
change:
<property name="hibernate.hbm2ddl.auto">create</property>
to
<property name="hibernate.hbm2ddl.auto">update</property>
in your hibernate.cfg.xml file.
Kindly post your hibernate.cfg.xml file if it the above solution doesn't work. We'll dig deeper into your code then.

Categories