ObjectOptimisticLockingFailureException on insertion in the partitioned table using spring data jpa - java

We have implemented the partitioning on a Postgres table using a flyway script.
In the flyway script, we are also creating a trigger defined as below -
CREATE TRIGGER raw_event_insert_or_partition
BEFORE INSERT
ON public.raw_event
FOR EACH ROW
EXECUTE FUNCTION public.raw_event_insert_or_partition();
public.raw_event_insert_or_partition() creates a partition if not exist and do the insertion.
Below is the complete flyway script for the reference -
CREATE OR REPLACE FUNCTION public.parcel_event_insert_partition()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
partition_date TEXT;
partition TEXT;
start_ts TIMESTAMP ;
end_ts TIMESTAMP ;
BEGIN
partition_date := to_char(NEW.carrier_status_time_gmt,'YYYY_MM_01');
start_ts := partition_date::timestamp ;
end_ts := start_ts + interval '1 month' ;
partition := TG_RELNAME || '_' || to_char(start_ts,'YYYY_MM_01') || '_' || to_char(end_ts,'YYYY_MM_01');
IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition) THEN
EXECUTE 'CREATE TABLE ' || quote_ident(partition)
|| ' (check (carrier_status_time_gmt >= ''' || start_ts || ''' '
|| ' AND carrier_status_time_gmt < ''' || end_ts || ''')) '
|| ' INHERITS (' || TG_RELNAME || ');';
EXECUTE 'CREATE INDEX ON ' || quote_ident(partition) || ' (carrier_status_time_gmt,carrier_code,value)';
RAISE NOTICE 'A partition has been created %', partition;
END IF;
EXECUTE 'INSERT INTO ' || quote_ident(partition) || ' SELECT(' || TG_RELNAME || ' ' || quote_literal(NEW) || ').* RETURNING id;';
RETURN NULL;
END;
$BODY$;
-- Register TRIGGER
CREATE TRIGGER parcel_event_insert_or_partition
BEFORE INSERT
ON public.parcel_event
FOR EACH ROW
EXECUTE FUNCTION public.parcel_event_insert_partition();
When we are running the insertion query in the PgAdmin console, it's working fine and data is getting inserted in the expected partition.
But when we are trying to insert the data using the save() method of the crudRepository we are getting the below error -
org.springframework.orm.ObjectOptimisticLockingFailureException: Unexpected row count: 0; expected: 1;
On enabling show_sql we are getting the below queries in the logs-
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into parcel_event (carrier_code,
carrier_status, carrier_status_code, carrier_status_time_gmt,
carrier_sub_status, carrier_sub_status_code,
carrier_sub_status_description, destination_location,
extra_info, status, status_code, status_description,
sub_status, sub_status_code, sub_status_description,
last_updated_at, latitude, location_code, location_name,
longitude, order_no, org_id, previous_status,
previous_status_time, status_identifier_value,
status_received_at, type, value, id) values (?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Any help is appreciated.

Related

Is there a way to avoid double select to check if not exists or value superior to n in an INSERT INTO

I would like to know if it's possible to avoid double select in this query to check if not exists at the same time that it checks if superior to X
PreparedStatement preparedStatement = connection.prepareStatement("""
INSERT INTO guilds_polls_user_choices (guild_id, poll_id, choice_id, user_id)
SELECT ?, ?, ?, ?
WHERE (SELECT vote_count FROM guilds_polls_user_vote_count WHERE user_id = ? AND poll_id = ?) < ? OR
NOT EXISTS(SELECT 1 FROM guilds_polls_user_vote_count WHERE user_id = ? AND poll_id = ?)
ON CONFLICT DO NOTHING;
""");
try this :
...
WHERE COALESCE((SELECT vote_count < ? FROM guilds_polls_user_vote_count WHERE user_id = ? AND poll_id = ?), TRUE)
see test result in dbfiddle

[Java][Spring] Insert query executed without error but data did not inserted

I have java application that execute native query, I have tried to execute the query using entityManager.createNativeQuery, jdbcTemplate, and java.sql.PreparedStatement.executeUpdate, none succeeded. The query completed without error, but no data is inserted.
Here's my actual SQL:
WITH stmt AS (
INSERT INTO account_statements (
amount,
sum_amount,
available_balance,
previous_available_balance,
hold_amount,
previous_hold_amount,
type,
note,
partner_id,
incoming_transfer_id
)
(
SELECT
?,
?,
(available_balance + ?),
available_balance,
hold_amount,
hold_amount,
?,
?,
?::uuid,
?::uuid
FROM account_statements
WHERE partner_id = ?::uuid
ORDER BY created_at
DESC LIMIT 1
) RETURNING id, available_balance, hold_amount), debit AS (
INSERT INTO journals (
amount,
type,
account_name,
account_statement_id,
partner_id
) (
SELECT
?,
?,
?,
id,
?::uuid
FROM stmt
)
), credit AS (
INSERT INTO journals (
amount,
type,
account_name,
account_statement_id,
partner_id
) (
SELECT
?,
?,
?,
id,
?::uuid
FROM stmt
)
)
UPDATE partners
SET
available_balance = (select available_balance from stmt),
hold_amount = (select hold_amount from stmt)
WHERE id = ?::uuid;
Not sure what I did wrong, but when I tried the SQL above in pg console and replace all the placeholders, it worked. Does anyone have an idea why the SQL above is not working?

BooleanBuilder clause generating longer sql query

I need to select items from a list of phone numbers which can have null value for some phone nos. The BooleanBuilder clause I am currently using is :
clause.and(QDashboard.dashboard.phoneList.any().number.isNull().
or(QDashboard.dashboard.phoneList.any().number.in(numbers)));
and the SQL query generated for the above clause is:
AND ( EXISTS
(SELECT 1
FROM phone_list pl
WHERE parent.id =pl.recordid
AND ( pl.number IS NULL )
)
OR EXISTS
(SELECT 1
FROM phone_list p2
WHERE parent.id =p2.recordid
AND ( p2.number IN ( ?, ?, ?, ?, ?, ?, ? ) )
)
I have noticed that this query is slower for large data-sets and would be faster if the SQL was something like this :
AND ( EXISTS
(SELECT 1
FROM phone_list pl
WHERE parent.id =pl.recordid
AND ( pl.number IN ( ?, ?, ?, ?, ?, ?, ? )
OR pl.number IS NULL)
));
How can I modify the BooleanBuilder clause to generate SQL query in the above format ?

java.sql.sqlexpcetion:ORA-00917:missing comma

I am sorry that i ask a very stupid question but i cant find the place where i miss the comma in the code..
sqlStr.append("INSERT INTO DS_GOAL ");
sqlStr.append("(DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID, DS_GOAL_ID, ");
sqlStr.append("DS_DESC, TO_CHAR(DS_PLAN_END_DATE, \"dd/MM/YY\"),");
sqlStr.append("DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER, ");
sqlStr.append("DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT, DS_FTE, ");
sqlStr.append("DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER ) ");
sqlStr.append("VALUES ");
sqlStr.append("(?, ?, ?, ?, ?,");
sqlStr.append("?, ?,");
sqlStr.append("?, ?, ?, ?,");
sqlStr.append("?, ?, ?, ?,");
sqlStr.append("?, ?, ?)");
sqlStr_insertGoal = sqlStr.toString();
After the
sqlStr.toString()
the console shows
INSERT INTO DS_GOAL (DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID,
DS_GOAL_ID,
DS_DESC, TO_CHAR(DS_PLAN_END_DATE, 'dd/MM/YYYY'),
DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER,
DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT,
DS_FTE, DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER)
VALUES (?, ?, ?, ?, ?,?, ?,?, ?, ?, ?,?, ?, ?, ?,?, ?, ?)
After Edited the code
the console shows
INSERT INTO DS_GOAL (DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID,
DS_GOAL_ID,
DS_DESC, DS_PLAN_END_DATE,
DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER,
DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT,
DS_FTE, DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER)
VALUES (?, ?, ?, ?, ?,?, TO_CHAR(DS_PLAN_END_DATE, 'dd/MM/YYYY'),?, ?, ?, ?,?, ?, ?,
?,?, ?, ?)
But the consoles shows invalid column index error
Thanks for help
I suspect your problem isn't actually a case of a missing comma (in my experience ORA errors are notorious for telling you the wrong thing). My suspicion is that your real issue is the use of " around the format string in your TO_CHAR call. To demonstrate, try this:
SELECT TO_CHAR(SYSDATE, "dd/MM/YY")
FROM DUAL;
If I run the above I get an ORA-00904: "dd/MM/YY": invalid identifier error. If I change the quotes to apostrophes instead:
SELECT TO_CHAR(SYSDATE, 'dd/MM/YY')
FROM DUAL;
I get 16/04/14. Double quotes are for identifiers, not strings:
SELECT TO_CHAR(SYSDATE, 'dd/MM/YY') AS "The Date"
FROM DUAL; // ^ This is an identifier
prints:
The Date
--------
16/04/14
EDIT:
Sorry, I should have spotted this one sooner! You're using TO_CHAR in your columns list, which you can't do. The below example nicely produces an ORA-00917: missing comma error:
CREATE TABLE JON_TEST (COL1 VARCHAR2(20));
COMMIT;
INSERT INTO JON_TEST (TO_CHAR(COL1, 'DD/MM/YYYY'))
VALUES (SYSDATE);
Whereas this works:
INSERT INTO JON_TEST (COL1)
VALUES (TO_CHAR(SYSDATE, 'dd/MM/YYYY'));
So you need to correct three things:
You need to change TO_CHAR to TO_DATE, and
You need to move the call to TO_DATE to your VALUES clause, and
You need to ensure that you use ' instead of " with the format string.
This is how Oracle define the syntax for INSERT statements:
Notice that in the middle section that it only says column_name and not sql_expression.
Try changing your query to the following:
sqlStr.append("INSERT INTO DS_GOAL ")
.append("(DS_SITE_CODE, DS_FINANCIAL_YEAR, DS_DEPARTMENT_CODE, DS_PLAN_ID, DS_GOAL_ID, ")
.append("DS_DESC, DS_PLAN_END_DATE, ")
.append("DS_CORP_OBJECTIVE, DS_CORP_OBJECTIVE_OTHER, DS_FOCUS, DS_FOCUS_OTHER, ")
.append("DS_TOTAL, DS_EQUIPMENT, DS_RECRUIT, DS_FTE, ")
.append("DS_CREATED_USER, DS_MODIFIED_USER, DS_GOAL_ORDER ) ")
.append("VALUES ")
.append("(?, ?, ?, ?, ?,")
.append("?, TO_DATE(?, 'dd/MM/YY'),")
.append("?, ?, ?, ?,")
.append("?, ?, ?, ?,")
.append("?, ?, ?)");
sqlStr_insertGoal = sqlStr.toString();

Getting error while executing dao

Hello friends i am running code given below which contains the setLogTimeEntery function and when this function is executed i am getting
"Error : java.sql.SQLException: ORA-00917: missing comma"
error and my database is oracle plese any one tell me wht is the problem.
public int setLogTimeEntery(Connection con, LogTimeBean ltb) {
int ans = 0;
try{
psmt=con.prepareStatement("Insert into TR_LogTime values((Select count(*) from Tr_LogTime) + 1 ,(select sysdate from dual) , Prj_Id=?,Area_Id=?,Actvity_Id=?,ID_No=?,Work_Date=(select to_date(?,'dd/mm/yyyy')from dual) ,Work_Hours=?,Division=?,Description=?,Remarks=?,Work_Week=?)");
psmt.clearParameters();
psmt.setString(1,ltb.getLt_Prj_Id());
psmt.setInt(2,ltb.getLt_Area_Id());
psmt.setInt(3,ltb.getLt_Actvity_Id());
psmt.setInt(4, ltb.getLt_ID_No());
psmt.setString(5, ltb.getLt_Work_Date());
psmt.setFloat(6,ltb.getLt_Work_Hours());
psmt.setInt(7,ltb.getLt_Division());
psmt.setString(8, ltb.getLt_Description());
psmt.setString(9, ltb.getLt_Remarks());
psmt.setInt(10, ltb.getLt_Work_Week());
ans=psmt.executeUpdate();
psmt.close();
}catch(Exception e){
System.err.println("Error : "+e);
}
return ans;
}
I don't think your Oracle SQL statement (as defined in the prepared statement) is valid. When using the insert into [table] values(...) syntax, you don't use column=value expressions.
If you're specifying all of the column values in the correct order, then use this:
psmt=con.prepareStatement("Insert into TR_LogTime values((Select count(*) from Tr_LogTime) + 1 ,(select sysdate from dual), ?, ?, ?, ?,(select to_date(?,'dd/mm/yyyy')from dual) ,?,?,?,?,?)");
Otherwise, if you're only specifying a subset of the columns, use the syntax of
insert into TR_LogTime (col1, col2, col3, ...) values (?, ?, ?, ...)
(I didn't specify the exact column names in your example since I don't know all of them)
More on this syntax.
try this:
Insert into TR_LogTime (XXX, YYY, Prj_Id, Area_id, Activity_Id, ID_No, Work_Date, Work_Hours, Division, Description, Remarks, Work_Week) values (
(Select count(*) from Tr_LogTime) + 1 , (select sysdate from dual) , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
You'll need to replace XXX and YYY with the appropriate column names

Categories