JDBC get database unique id for a record - java

I would like to know if there is any way of getting a database's identifier for a record through JDBC.
For example, i am querying the database and getting back a ResultSet which i store in a Map. I give an Id to each record based on the order that i retrieve them from the ResultSet.
Now i would like to re-query the Database and be able to correlate the new ResultSet to my already existing records. So, if a record got deleted, ideally, i would be able to just remove it from the Map by using the unique identifier.
My problem here is that i cannot find a unique identifier coming from the RDBMS itself. I tried using the ResultSet.getRowId() but this method is not implemented by all JDBC driver providers.
Could anyone thing of any way to get a get an identifier from the ResultSet that uniqely identifies a record in the Database ?
Thanks.

Ideally, every Record in your database should have an identifier (Primary Key). The best approach is always try to stick to this.
So, if a record got deleted, ideally, i would be able to just remove it from the Map by using the unique identifier.
Maybe clearing the Map and mapping it again would be an option.

Why can't you use the primary key to identify the record?

Related

Parallel save giving a duplicate key error in Spring R2DBC

I am getting a duplicate key error from the database (MySQL) for the scenario I have explained below.
Background
I need to save an entity to my database, but the entity id is not managed/generated by my system, so it comes from 3rd party with an id and I need to save it with its id. When our application does not manage its id, Spring Data(R2DBC) cannot know if it is a new entity or not because there will be an id on it all the time. According to their documentation, there are several ways to tell Spring if it is a new entity or not, so I have chosen to implement a Persistable entity so that I can tell Spring if it is a new entity. However, I need to query DB to understand if it exists or not. Please note that I am using Spring reactive so putting a synchronized keyword is not a solution for me...
Here is the problem
Imagine that 2 requests come almost at a time. For the second request, it will query the DB and get nothing since the first request has not been saved yet. It will decide to create the second request, but at that point, the first request is committed to DB, and as a result, the second request will get a duplicate key error since I told Spring that it is a new one.
I have been thinking of solutions to solve this problem but I couldn't find any yet... I would really appreciate it if you could help me on this matter.
Thank you in advance!
You're gonna have the same problem with pretty much any entity system. Let me explain: Let's say we have a register endpoint. Two people register at the exact same time using the exact same email address. Then both are gonna be saved to the database since R2DBC does the same flow taking the exact same time for both requests.
The simplest solution for this problem is not checking the email at all and just accepting that you're not gonna deal with it with your own code. Instead you can change the database schema for your table. I don't know how you create your table but I just use a sql file with the code for it inside. In my case by making the email column UNIQUE we can prevent this problem in the database instead of preventing it using our own logic. My schema file for the accounts table looks like this:
create table if not exists accounts (id SERIAL NOT NULL, username VARCHAR(32), rank VARCHAR(32), email VARCHAR(32) UNIQUE, password VARCHAR(512), invitor INT, data TEXT, PRIMARY KEY (id));
You can also check out the w3schools article about the UNIQUE constraint.

Check duplicate value before insertion using Hibernate

I am using Spring+Hibernate for my application. I have a few CRUD operations. Before inserting, I need to check if a similar entry is already in the database, if yes it should not be inserted.
For eg: If I am trying to create a Department, before inserting the row, I should check if a department with the same name already exist or not. If yes, the method returns error message.
Now, I know the unique key constraint can be set on the column to do the check. But, I want to know if there is any other way to do this.
The only way I can think of is first fetching all the departments from the database and check against each object.
Please let me know if there is any other way.
The only way I can think of is first fetching all the departments from the database and check against each object.
You don't need to fetch all departments form the database. It should be enough to search the database for the department with the name you want to insert. Since the name should have a unique key anyways it should be fast enough.
If your #Id attribute is department name, then the saveOrUpdate API of Hibernate will check if an object with that id is already present in the DB. If so it will update, else it will create a new entry. Hope this should help you. See this link.
You can try find object from database by "get" method:
Cat cat = (Cat) sess.get(Cat.class, id);
If received object is null, you can add new.
Also for performance better use query with "count" predicate, for avoid whole object loading.

JOOQ API getPrimaryKey() returns null to each table?

I have noticed that in JOOQ API the "tableByName("table_name").getPrimaryKey()" returns null. I guess this is because there is no real query happens in the background. Is it possible to force JOOQ API to check the table and read the meta data? Or this can be done only through querying the org.jooq.util.Database instances?
A Table object constructed with DSL.tableByName() is not connected to a database, so it couldn't dynamically fetch primary key information even if this was supported.
You can, however, get primary key information through DSLContext.meta().getPrimaryKeys()

Getting timestamp of last insert in mysql along with primary key in a single query?

I tried searching for the solution to this problem but am still stuck. Seems rather simple (or maybe it's my ignorance :)
I already fetch the 'auto incremented' primary key after inserting. My question is can I retrieve the timestamp of the last insert WITHOUT sending a second query of SELECT m.timestamp from My_Table m where id = 123; //i.e., 123 is the id of the row that was just created
It seems wasteful to go back and forth but is that really the way to do it?
I'm using Spring's JDBCTemplate to query the MySQL DB.
What is important is getting the last inserted id. Check this
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
Sometimes, there is no easy way.

How can I get the column name of the primary key of a Database Table from the ResultSet or ResultSetMetaData object in JAVA?

I am writing a Java Application. I have got a ResultSet. Now I want to find out the coloumn name of the primary key of the table.
Is it possible to get that coloumn name through ResultSet object or ResultSetMetaData Object or any other way.
I didn't find any way to find this.
No. You will not get that information from ResultSet or ResultSetMetadata.
What you want to use for that is DatabaseMetadata class. From that class check getPrimaryKeys method to get the information you want.
Of course, to use this, you will need to know the name of the table.
I want to add, if in a table you have autoincrement field, it must be the primary key. So, your code could look like this:
if(metaColumn.isAutoIncrement(i)) {
primaryKey = metaColumn.getColumnName(i);
i=nColoumn+1;
}
It uses ResultSetMetaData.
A nice tool which you can use to verify the metadata information is dbVisualizer.
It uses the JDBC metadata to retrieve table definitions and other parts of the database. Schema and Catalog are columns in the table definition view - so you can check which values are in these columns for your favorite database.
dbVisualizer is available in a free basic version.

Categories

Resources