Getting the result of an auto_increment key after a save - activejdbc

I am trying to solve a problem of disconnected clients while using activejdbc. So the client app queues the inserts and subsequent updates and deletes when there is no internet. Then the batch of these come thru when they have connectivity.
To support this the client uses temporary primary keys which are replaced with the result of the the auto_increment key produced when the connectivity is restored and the batch applied. To do this I need to get the key generated when I do a save() or create(). Can activejdbc use https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#getGeneratedKeys%28%29 ?

When you save a model, its ID is in fact becomes the auto-generated value returned by the database:
Person p = new Person();
p.set("first_name", "John", "last_name", "Doe");
p.saveIt();
System.out.println("ID of this model: " + p.getId());
However, if you try to set the ID of a model manually, then the framework assumes you know what you are doing and tries to use that ID in the insert.
Please, see: http://javalite.io/surrogate_primary_keys.

Related

How to get Liquibase to add more data to DATABASECHANGELOGLOCK table?

In our build server, we have a number of feature branches get deployed against one database. The problem is sometimes some buggy scripts in one branch causes LB to exit without releasing the lock. The problem is there is no easy way to find out what branch caused this. We may have up to 30 branches getting deployed constantly as there are new changes against the branch.
Is there any way (or can we have new feature in Liquibase) to set the instance name and the name can be stored in LOCKEDBY column of table DATABASECHANGELOGLOCK so we can easily find out what branch/instance caused the issue?
Currently, LOCKEDBY has only IP in it which is the same for all the instances.
You can specify a system property which gets insert into the LOCKEDBY column:
System.setProperty("liquibase.hostDescription", "some value");
I think to achive this you need to patch Liquibase somewhere here:
https://github.com/liquibase/liquibase/blob/ed4bd55c36f52980a43f1ac2c7ce8f819e606e38/liquibase-core/src/main/java/liquibase/lockservice/DatabaseChangeLogLock.java
https://github.com/liquibase/liquibase/blob/ed4bd55c36f52980a43f1ac2c7ce8f819e606e38/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java
to fetch additional variable somehow (property file/env variable/etc) and store in the table.
Btw, be careful with deploying multiple branches with the same database instance, because it is possible that you will make a change in DB structure for one branch, that will break another one.

mule returning primary key on successful insert

Hi there I'm new to Mule and I needed pointer on how to process records. I'm trying to perform an operation where I insert a new record into one table and if the record is inserted successfully, obtain the primary key and insert it into another table where the primary key is part of the foreign key.
I don't know which connector or component to use to check if an insert was successful so that I can insert the primary key into another table.
My primary key is a uuid generated as a variable. I tried returning the GUID from sql server using using the following documentation but it didn't work. Any help or pointers on either question will help.
https://doctorjw.wordpress.com/2015/10/01/mule-and-getting-the-generated-id-of-a-newly-inserted-row/
If you want a DB-generated Id, you can use two DB blocks, saving a variable between them:
1st DB block: generate an unique Id throw a sequence, in example:
select GENERAID_ESB.nextval from dual
Save variable (Session or Flow, depending on your required scope for it):
#[payload.get(0).nextval]
2nd DB block: insert your record in DB with unique id saved, in example:
INSERT INTO ESB_TABLE values(#[(sessionVars.'idTable')],
#[message.outboundProperties.'yourInformation'])**
I hope this helps.

UPDATE failed due to key violation VBA SQL Access

I need help with this
I have an MS Access db form which will enable users edit details about a project and the new values entered will be saved to the db table when the save button is clicked I am using the sql UPDATE syntax to do this and my code is similar to below
Private Sub Save_Click()
ltemp = " UPDATE Table1 "
ltemp = ltemp & " SET ClientName = 'ANN' "
ltemp = ltemp & " WHERE ProjectID = 2333 "
CurrentDb.Execute (ltemp)
End Sub
with this code, nothing happened. The code would execute with no errors but the value on the table wouldnt change.
I tried the code
DoCmd.RunSQL " UPDATE Table1 SET ClientName = 'ANN' WHERE ProjectID = 2333"
with this i got a long error message which indicated that the records couldnt be updated due to key violation. The problem is that the field 'ClientName' is not the primary key, although it is linked (in a relationship) to the primary key of another table.
both codes work to update other fields except this one which is in a relationship with the primary key of another table.
Obviously there is no record in your 'client' table with the 'ANN' id, so it cannot be set as a valid value for the corresponding\foreign key field in your updated table.
currentDb.execute instruction will not return any error message (not like the 'DoCommand' one) because it's not supposed to, as long as the syntax is correct (see below). You could try to use the currentDb.RecordsAffected to check if any record was changed by your instruction. Check parameters available for the execute method for further details.
Access Help:
"In a Microsoft Jet workspace, if you provide a syntactically correct SQL statement and have the appropriate permissions, the Execute method won't fail — even if not a single row can be modified or deleted. Therefore, always use the dbFailOnError option when using the Execute method to run an update or delete query. This option generates a run-time error and rolls back all successful changes if any of the records affected are locked and can't be updated or deleted."
You are attempting to violate the referential integrity set up on your database.
As you've noted, there is another table, which will look something like this:
CREATE TABLE Client
(
ClientName VARCHAR(100),
... other client fields here
);
And there is a FOREIGN KEY setup between columns Table1.ClientName and Client.ClientName.
To avoid this, either:
INSERT a client with the name ANN into the other table
DROP the foreign key constraint on Table1.ClientName if you intend to violate the constraint (but note that joins may fail when the client is missing)
Change the design and start using surrogate keys, such as ClientID and referencing the Surrogate key in your other tables (instead of 'natural' keys like Client Name). This way, clients can get married, change their names etc and your database won't break :)

Copy database with data and foreign keys without identity insert on

Scenario:
I have a set of test data that needs to be deployed to our build server daily (our build server database is first overwritten with the current live database, and has all data over a month old removed).
This test data has foreign key references within it which need to stay.
I can't simply switch on IDENTITY_INSERT as the primary keys may clash with data that is already in the database (because we aren't starting from a blank database).
The test data needs to be able to be regenerated fairly regularly, so the though of going through the deploy script and fudging the id columns to be something outlandish (or a negative number for instance) and then changing the related foreign key columns to be the same id every time we regenerate the data doesn't thrill me.
Ideally I would like to know if there is a tool which can scan a database, pick up the foreign key constraints and generate the insert scripts accordingly, something like:
INSERT INTO MyTable VALUES('TEST','TEST');
DECLARE #Id INT;
SET #Id = (SELECT ##IDENTITY)
INSERT INTO MyRelatedTable VALUES(#Id,'TEST')
It sounds like you want to look into an ETL process that copes with the change in id. As you're using SQL Server, you can look at the OUTPUT clause - use this to build up some temporary tables that can map the "old" id to the "new" id for each primary key to map the foreign keys when migrating the "child" tables.

Subsonic 2.0.3: Save() causes problem due to identity field constraint

Here's a strange one. I'm using SubSonic 2.0.3 to insert a new row into a given table.
The table includes an int identity field that is set up properly in the database (Identity seed = 1, Identity increment = 1). Obviously I do not explicitly set this value before calling .Save().
Ever since I rebuilt my development DB (copying from my prod DB), the .Save() fails with the message:
"The INSERT statement conflicted with the CHECK constraint \"repl_identity_range_tran_661577395\". The conflict occurred in database \"blah\", table \"dbo.ScheduledEmails\", column 'MyIdentity'"
The database is replicated, and I didn't explicitly create that constraint. To be honest, I don't understand the constraint, since the condition is ([MyIdentity]>(7) AND [MyIdentity]<(20000)). The constraint from the Prod DB has different numbers, but it's the same format as this one from my Dev DB.
Any clues about this bizarre issue?