Get the last inserted id from table in hibernate from MySql database - java

I have an entity named Item in which i have declared a property
#Column(name="ITEM_CODE", unique = true, length=30)
private String itemCode
while inserting a new item in the corresponding table i am trying to generate a unique code by prefixing it PRO- and then concatenating a random number generated by using Random class.
I am also trying to get the last item id inserted in the database and add 1 with the id and then add it to the product code as suffix.
My code to fulfill my purpose is
public String generateItemCode() {
String query = "SELECT max(i.id) FROM ITEM i";
List list = sessionFactory.getCurrentSession().createQuery(query).list();
int nextInsertId = ((Integer) list.get(0)).intValue() + 1;
Random random = new Random();
int number = random.nextInt(9999 - 1 + 1) + 1;
return "" + number+nextInsertId;
}
I have also tried by using this line of code in the method body.
int maxId= (Integer)sessionFactory.getCurrentSession().createQuery("select max(id) from items").uniqueResult();
the above code is not working.
How can i get the last inserted id. Is there any simpler way to do it?
Thanks in advance.

It appears your issue may likely be because of your query syntax mimicing that of native SQL when in reality you aren't asking Hibernate to execute a native query but instead a HQL/JPQL query.
If we assume your entity is named Item with an identifier property named id, you would use:
SELECT max(i.id) FROM Item i
You'll notice I use the property name id and the entity name Item (case is important here).
To put the pieces together, the following should work:
// be sure to check for null lastId in case you have no items.
final String sql = "SELECT max( i.id ) FROM Item i";
Integer lastId = (Integer) session.createQuery( sql ).uniqueResult();

Related

Retrieve and update field java

Using Java I want to obtain all IDs from my database and select GW_STATUS if it is equal to 0. I used the following SQL statement to achieve this.
PreparedStatement get_id = con.prepareStatement("SELECT ID from SF_MESSAGES where GW_STATUS = 0");
Once the IDs have been obtained, I want to update GW_STATUS to 1 according to their ID as demonstrated in the code below but only one field is being updated when I execute the code.
PreparedStatement update = con.prepareStatement("update SF_MESSAGES set GW_STATUS=? where ID = ?");
update.setInt(1,1);
ResultSet x = get_id.executeQuery();
while(x.next()){
int uber = x.getInt(1);
int array[] = new int[] {uber};
for (int value : array) {
System.out.println("Value = " + value); //Successfully obtains and prints each ID from the databse table
update.setInt(2,value); // Only one ID is updated therefore only field updated
}
}
int result = update.executeUpdate();
System.out.println(result + " Records updated");
I've tried using another update statement within the for loop to update every ID obtained but that doesn't work too. How can I successfully update every field according to their ID?
You can make the whole processing much simple. It turns out that you just want to update SF_MESSAGES which have GW_STATUS equals to 0, so your query can look like the following:
update SF_MESSAGES set GW_STATUS=1 where GW_STATUS=0
Therefore, you do not have to fetch IDs, loop over them so it is more efficient solution.

Can I compare resultsets like this? I'm facing the below error

I have 2 ResultSets. 1st ResultSet contains the records from table1 from database1 and 2nd ResultSet contains the records from table2 from database2. I need a list of records from resultset1 which are not present in resultSet2. For this I wrote this logic but it is not working and throwing me the following error.
java.sql.SQLException: Invalid operation for read only resultset: deleteRow
if ( table1ResultSet != null )
{
while ( table1ResultSet.next() )
{
final String table1Record = table1ResultSet.getString( 1 );
if ( table2ResultSet != null )
{
while ( table2ResultSet.next() )
{
final String table2Record = table2ResultSet.getString( 1 );
if ( table1Record.toString().equalsIgnoreCase( table2Record.toString() ) )
{
table1ResultSet.deleteRow();
break;
}
}
}
}
}
return table1ResultSet;
That exception says what the problem is - your result set doesn't support delete. In order to have updateable result set there are some requirements:
When you prepare statement did you make it with ResultSet.CONCUR_UPDATABLE?
A query can select from only a single table without any join operations.
The query must select all non-nullable columns and all columns that do not have a default value. A query cannot use "SELECT * ". Cannot select derived columns or aggregates such as the SUM or MAX of a set of columns.
You might want to move the results sets into Java sets before working doing what you are doing though because using deleteRow will actually delete the row from the database (unless that's the expected result)
There is another problem with your code though. Even if delete works your code will fail on the second iteration of result set 1 because you never reset table2ResultSet and for the second iteration there won't be more results in table2resulset.
But on top of all that. Why would you go through all that hussle and get all that rows that you don't need instead of doing it with one single query like:
select * from table 1 where id not in select id from table 2
or
delete from table 1 where id not in select id from table 2
if that's the goal
Your logic:
Assumes the records come in some order (which may or may not be true, depending on your SQL)
Consumes the entire result set 2 for each row of result set 1, which is unlikely your intent
Deletes things, which is also not what you mentioned in the question
Your question can be implemented easily as such:
Set<String> list1 = new HashSet<>();
while (table1ResultSet.next())
list1.add(table1ResultSet.getString(1).toLowerCase());
while (table2ResultSet.next())
list1.remove(table2ResultSet.getString(1).toLowerCase());
System.out.println(list1);
This will print all the values (without duplicates) that are present in the first result set, but not in the second.

SQL query use to return latest ID from mysql database, not it returns 99999

My server would retrieve the latest ID from the database, now it is stuck and keeps returning the id 99999, even though the latest id is now 100040
My code is:
String insertTable = "SELECT * FROM dutyofcare ORDER BY Id DESC LIMIT 1";
ps = conn.prepareStatement(insertTable);
rs = ps.executeQuery();
String ResultS = "";
if (rs.next()) {
ResultS += rs.getString("Id");
}
The issue is that the ORDER BY in your query is doing a lexical (character-by-character) sort where 9 always comes after 1, and not numeric sort which handles the digit positions. This is because of the column type of ID. What you need is to ensure ID is a number before the sort is done.
Either change your ID to a numeric column type and run below query:
SELECT MAX(ID) from dutyofcare;
Or if you want to retain your column type (less efficient than above option):
select MAX(cast(ID AS UNSIGNED)) from dutyofcare;
Or if you want to retain your column type AND just fix your existing query (least efficient of all the options)
select * from dutyofcare order by CAST(ID AS UNSIGNED) desc limit 1;
All these methods basically treat the ID as number and choose the biggest value.

Trying to pass a Java variable into a sql string

I've had a look around on the web but can't seem to find a definite answer to my question.
Basically, I have a database and table that are successfully working. Now I want to read each line from my table one by one and store the result into a array and I am trying to use a for loop to be more professional rather then using repetition.
I have this code
for (int i=1; i<=8; i++)
{
String query = "Select * FROM Table1 WHERE ID = i";
Rs = St.executeQuery(query);
COL1Title[i] = Rs.getString("CO1Name");
COL2Age[i] = Rs.getString("CO2Rating");
}
The for loop is in a try catch statement and it's complaining with the error "Unknown column 'i' in 'where clause'"
Im guessing there's a certain way for how variable i is to be inserted in the the query.
I should point out ID is a column that has the auto increment feature added on and is primary key if that helps
Could anyone help me out here?
First, we can simplify the task be executing a single query. Note the addition of the range limit and the ORDER BY - without an ORDER BY the results have an unspecified order!
PreparedStatement stmt = "Select ID, CO1Name, CO2Rating"
+ " FROM Table1"
+ " WHERE ID >= ? AND ID <= ?"
+ " ORDER BY ID";
And bind in placeholders (unless there is good reason otherwise, always use placeholders when injecting data into a query). The values could have been hard-coded above in this case, just as they are hard-coded in the for-loop, but the binding is shown here for future reference:
stmt.setInt(1, 1);
stmt.setInt(2, 8);
Then execute the query:
ResultSet rs = stmt.executeQuery();
And iterate the results. Note that rs.next() must be invoke once before any column is read (the cursor starts before any records) and, in this case, it makes it easy to handle a bunch of results.
while (rs.next()) {
int id = rs.getInt("ID");
String title = rs.getString("CO1Name");
String name = rs.getString("CO2Rating");
// do stuff with this record
}
Note that even though the ORDER BY guarantees that the results are iterated in order of ID, assuming a database cardinality rule ensures each result has a unique ID, there may be 0 to 8 records returned - that is, non-existent records may need to be detected/handled separately.
Also (but not shown), make sure to cleanup (close) the ResultSet when done: use a try/finally or try-with-resources construct.
You need to pass i in string as integer, Replace line by:
String query = String.format("Select * FROM Table1 WHERE ID = %d",i);

java- generate id (combination of string and integer)

I am making an application in NetBeans (java). This application has unique id combination of string and integer like abc/111 or xyz/253 and the integer part should increase by when a new entry takes place in the database i.e. abc/112 and xyz/254.
The problem is the value of integer part increase until it has reached 10 in a proper way but after that it does not increase and remain same for further entries in database.
I used the following code -
try{
String sql = "SELECT RegNumber FROM Death ORDER BY RegNumber DESC ";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
if (rs.next()) {
String add1 = rs.getString("RegNumber");
String[] parts= add1.split("/");
String part1= parts[0];
String part2= parts[1];
int a,b;
a= Integer.parseInt(part2);
b=a+1;
jTextField20.setText(""+part1+"/"+b);
JOptionPane.showMessageDialog(null, "done");
}
}
"Integer part increase till 10" means that if I start the first value of id in database like abc/1 then new id generates automatically for the next entry with the increasing value 1 that is abc/2 and for next entry it is abc/3 and so on in sequential order like this: abc/4, ..., abc/10
But when it has reached abc/10 the new generated id remains same i.e. abc/10 for every new entry in database. (I am using MS Access 2007 and the id is of text type). The first id in the database is created by the application itself.
If anyone has another alternative to generate id, please tell me.
The problem is that
String sql = "SELECT RegNumber FROM Death ORDER BY RegNumber DESC ";
will sort on descending alphabetic order, and alphabetically speaking
"abc/9" > "abc/10"
and that's why your program always fetches 9 over and over again...
I think you will have to split up that column for storage, and store the numeric part as an actual number type in the database. That's probably not as hard as it sounds, you can always sort on 2 fields
String sql = "SELECT RegNumber FROM Death ORDER BY RegString DESC, RegNumber DESC ";
You could also consider using a SERIAL (autoincrement) datatype for the RegNumber part in certain cases (ie if RegNumber is not reset eg when the string part changes) to simplify your insertion logic further.
Your select query is sorting the entries in desc order, which are Varchar type
"SELECT RegNumber FROM Death ORDER BY RegNumber DESC "
Which means after sorting its getting values as
abc/9, abc/8, abc/7, abc/6, abc/5, abc/4, abc/3, abc/2, abc/10, abc/1.
Which means first id is 9 always, which means next value would be 10 always.

Categories

Resources