Question

I have an Insert statement to a table which has a primary key of dep_id and emp_id. My java program generates a new emp_id for a new record and inserts it. What is happening is if for example, I have dep_id = 100 and emp_id = 25, I am not able to insert a record where dep_id = 100 and emp_id = 26, but I can for dep_id = 100 and emp_id = 27. I checked thru select statements if something of that combination (dep_id = 100 and emp_id = 26) exists. There is nothing of that sort. I still did a DELETE from where dep_id = 100 and emp_id = 26 and Commit just to be sure and then tried to insert, but still it does not work. What might be wrong? Follwing is the code: Modified DDL and Insert statement(Obtained from Eclipse console)

                                                                                    CREATE  TABLE "TestDB"."table1" 
 (  "dep_id" NUMBER(20,0), 
"emp_id" NUMBER(20,0), 
"STATUS" VARCHAR2(10 BYTE), 
"PRO_LEVEL" VARCHAR2(14 BYTE), 
"new_sql_stmt" VARCHAR2(4000 BYTE), 
"DEL_TEM" VARCHAR2(500 BYTE), 
"tab_name" VARCHAR2(4000 BYTE), 
"COL_NAME" VARCHAR2(4000 BYTE), 
"QUERY_TYPE" VARCHAR2(4000 BYTE), 
"NAME" VARCHAR2(4000 BYTE), 
"DT_MODIFIED" DATE DEFAULT SYSDATE

)

  CREATE UNIQUE INDEX "TestDB"."table1_PK" ON "TestDB"."table1" ("dep_id", "emp_id") 


     INSERT into table1            (dep_id,emp_id,status,new_sql_stmt,tab_name,col_name,query_type,NAME)values('100','26','Unlock','INSERT into testTab(id_some,nm_some,id_some_origin,flag,some_code,author,order) values  (''S11111111'',''trialSome00'','''',''y'','''',''100'',0)','testTab','nm_some','INSERT','trialSome00')

Please note that the Insert statement itself has another Insert statement as the value. This Insert statement(The main one) is used in many other places in the app. Also, The dep_id that I use 100 is a test dep_id. Nobody uses it but me.

Was it helpful?

Solution

Create an Oracle sequence:

CREATE SEQUENCE emp_id_seq MINVALUE 1 START WITH 1 INCREMENT BY 1; 

Now you can either call the "nextval" method on that sequence (this can be done with JDBC or almost every ORM if not all of them) from within your code, or you can place a trigger on that column that automatically gets the nextval from the sequence and inserts it in the table any time you do an insert (IIRC on oracle you would use the 'BEFORE INSERT' operator in your trigger).

e.g.

create or replace trigger mytable_emp_id_trigger
before insert on mytable
for each row
begin
    select emp_id_seq.nextval into :emp.id from dual;
end;
/

Doing it this way is thread safe and you should never see a conflict like this occur.

If you insist on doing it within java code (say the DBA's won't let you create another sequence, but why-ever not I'd be surprised if they didn't), then you'll have to make that method thread safe. Likely best to create a singleton (you can create singleton EJBs) with a synchronized method to provide the next value. You get your id's from that singleton class, not any other class or ejb to avoid issues like you are having now (whether or not the current issue is because of this, what you are experiencing now is typical of multiple threads coming into conflict with unsynchronized methods in a multithreaded environment).

In the meantime, make use of your debugger and watch your variables to see what your existing code is producing if you really want to understand what is happening. Debuggers and watches are your friends. Your best friends.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top