the_narv wrote:
The questions below relate to Oracle 8i and 9i in particular.
Firstly, all the tables in the database I wish to generate code for have their primary key set by a trigger on insert. This cannot be changed in the short term as there is a lot of existing code that relies on this particular method. Setting the primary key column as a sequence in LLBLGen does not achieve the correct result because it gets a value for the sequence before the insert, and then the database overwrites that key with a new one. Is there any other method that anyone is aware of where I can get the key value from the entity class, or am I better trying to amend the template to get the sequence CURRVAL immediately after an insert? If this is the case then some pointers on where to start would be very much appreciated.
The problem is: the insert query consists of 2 parts: a sequence part and the actual insert. As the DQE doesn't know better, it sets the sequence part to be executed before the actual insert. The sequence has to grab the nextval as it doesn't know any better, and passes on the value to the pk field value.
Changing the NEXTVAL sequence directive to CURRVAL doesn't matter, as that will not make the sequence part be executed after the insert, as the DQE doesn't have information about the trigger. The only 'solution' is that you alter the DQE source for oracle and make it execute after the insert, and change "NEXTVAL" into "CURRVAL". It's 2 lines of code you have to change. I haven't tested that though, so it might not work with these simple changes, but it is possible to change these lines to make it work. As all tables in your project use this, it's no problem to change this in the DQE. You only have to make sure that if an update to the DQE comes in, you have to change these lines again. I can't fix this in the current code, as it requires information that's not there. I'll try to fix this in the upgrade in development.
So change:
193: sequenceQuery.ExecuteSequenceCommandFirst = true;
194: sequenceQuery.SequenceRetrievalCommand.CommandText = String.Format("SELECT {0}.NEXTVAL FROM DUAL", persistenceInfo.IdentityValueSequenceName);
into
193: sequenceQuery.ExecuteSequenceCommandFirst = false;
194: sequenceQuery.SequenceRetrievalCommand.CommandText = String.Format("SELECT {0}.CURRVAL FROM DUAL", persistenceInfo.IdentityValueSequenceName);
The second problem is how best to create a new entity that is an exact copy of an existing entity, differing only by the primary key. In other words I want to duplicate a row in a table.
fetch entity,
set isnew to true
set pk fields (if you use a natural pk)
set entity.Fields.IsDirty to true
set all IsChanged flags to true of all teh entity.Fields[index] instances.
save