Records in DB are not one by one. Hibernate - java

I have db table Users with two columns : ID (AI) and NAME (UNIQUE).
When I'm adding new record to db everything is ok, this record has ID = 1.
When I'm trying to add record with existing name I'm getting error:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry
I want to add next record, with valid data and this record has ID = 3.
Is any solution to avoid it? I want to have have ID's like this:
1 | 2 | 3
not
1 | 3 | 5 etc.
or maybe should I first check if this name exist? Which option is better?
My code:
public boolean save(){
hibernate.beginTransaction();
hibernate.save(userObject);
hibernate.getTransaction().commit();
hibernate.close();
return true;
}

There are different ID generation strategies. If ID is generated based on sequence then its last number is immediately incremented whenever "next value" is requested. There won't be a problem you described if ID is generated based on table.

Related

Simple SQL query on highest ID

I unsuccessfully attempted to leverage Java's DerivedQueries but cannot accomplish the required result so I have to manually write a SELECT Statement.
I want to display one single record in my UI. This should be the most recently generated record (which means it has the highest ID Number) associated with a category that we call "ASMS". In other words, look through all the rows that have ASMS#123, find the one that has the highest ID and then return the contents of one column cell.
ASMS: Entries are classified by 11 specific ASMS numbers.
ID: AutoGenerated
PPRECORD: New entries being inserted each day
I hope the image makes more sense.
//RETURN ONLY THE LATEST RECORD
//https://besterdev-api.apps.pcfepg3mi.gm.com/api/v1/pprecords/latest/{asmsnumber}
#RequestMapping("/pprecords/latest/{asmsNumber}")
public List<Optional<PriorityProgressEntity>> getLatestRecord(#PathVariable(value = "asmsNumber") String asmsNumber) {
List<Optional<PriorityProgressEntity>> asms_number = priorityprogressrepo.findFirst1ByAsmsNumber(asmsNumber);
return asms_number;}
The ReactJS FE makes an AXIOS.get and I can retrieve all the records associated with the ASMS, but I do not have the skill to display only JSON object that has the highest ID value. I'm happy to do this in the FE also.
I tried Derived Queries. .findFirst1ByAsmsNumber(asmsNumber) does not consider the highest ID number.
Try this:
SELECT pprecord FROM YourTable WHERE id =
(SELECT MAX(id) FROM YourTable WHERE asms = '188660')
Explanation:
First line select pprecord, second line select the id
I'll improve the answer if any additional question. Upvotes and acceptions are appreciated~

How to lock row in mysql that access from 2 difference instance application?

I have a problem with mysql query i am using SELECT ... FOR UPDATE to locking a row in my table data source so that two instance application cannot get the same row at the same time. But when i test with jmetter to hit my program, sometime mysql return the same value.
The goal is i want to select example :
i have a table that have id | name | last_seq
so when my 1st instace application select that row will add 100 to last_seq.
so the value for that rows now is 1 | opr_sequece | 100
and when my 2nd instance application select that row will add 100 to last_seq.
so the value for that rows after selection from 2nd instance is 1 | opr_sequence | 200.
but when i run, sometimes 2 instance applications get same value and update the same value too to table.
i do SELECT ... FOR UPDATE but it sill happend.
Please help me
UPDATE
public synchronized String constructTraceNo(){
if(counter % 100 == 0){
OprSeq oprSeq= oprSeqRepo.findByNm("opr_sequence");
//update to repository
counter = oprSeq.getLastSequence();
oprSeq.setLastSequence(counter+100);
oprSeqRepo.save(oprSeq);
}else if(counter == 999999){
OprSeq oprSeq= oprSeqRepo.findByNm("opr_sequence");
counter = 0;
oprSeq.setLastSequence(counter+100);
oprSeqRepo.save(oprSeq);
}
counter+=1;
return padding(String.valueOf(counter),6,"0",0);
}
OprSeq oprSeq= oprSeqRepo.findByNm("opr_sequence"); this will select the row and the update below that selection.
There are many ways that can generate the same result. Some of them are:
Use autocommit instead of explicit transactions
Don't update the record but only selecting it (for example update the record only if a condition is satisfied)
Try catch the code so that in case of a failed update there is no rollback
If some code reset values or decrement values
You should investigate the different possibilities or post an updated question with the full code.

How to update multiple rows using a single query with a mutable colletion

I want to update rows on a table which contains the following colums:
`parameter_name`(PRIMARY KEY),
`option_order`,
`value`.
I have a collection called parameterColletion which contains "parameterNames", "optionOrders" and "values". This collection does not have a fixed value, it can receive the quantity of parameters you want to.
Imagine I have 5 parameters inside my collection (I could have 28, or 10204 too) and I am trying to update the rows of the database using the next query. Example of query:
UPDATE insight_app_parameter_option
SET option_order IN (1,2,3,4,5), value IN ('a','b','c','d','e')
WHERE parameter_name IN ('name1', 'name2', 'name3', 'name4', 'name5')
But this isn't doing the job, instead it gives back an error which says You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IN (1,2,3,4,5), value IN ('a','b','c','d','e') WHERE parameter_name IN ('name1'' at line 2
1,2,3,4,5 -> Represent the option orders inside parameterCollection.
'a','b','c','d','e' -> Represent the values inside parameterCollection.
'name1', 'name2', 'name3', 'name4', 'name5' -> Represent the names inside parameterCollection.
I know how to update each parameter by separate but i would like to do it all together. Here are some links I visited where people asked the same question but they used a fixed colletion of objects, not a mutable one.
MySQL - UPDATE multiple rows with different values in one query
Multiple rows update into a single query
SQL - Update multiple records in one query
That's not possible with MySQL. The error you are receiving is a syntax error. You are not able to set multiple values at once. This is the correct syntax to a UPDATE statement: (ref)
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET assignment_list
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
value:
{expr | DEFAULT}
assignment:
col_name = value
assignment_list:
assignment [, assignment] ...
You need to create separate UPDATEs for each row. I suggest executing all in a single transaction, if its the case.
The correct syntax for your example is:
UPDATE insight_app_parameter_option
SET option_order = 1, value = 'a'
WHERE parameter_name = 'name1';
UPDATE insight_app_parameter_option
SET option_order = 2, value = 'b'
WHERE parameter_name = 'name2';
UPDATE insight_app_parameter_option
SET option_order = 3, value = 'c'
WHERE parameter_name = 'name3';
...

ORMLite groupByRaw and groupBy issue on android SQLite db

I have a SQLite table content with following columns:
-----------------------------------------------
|id|book_name|chapter_nr|verse_nr|word_nr|word|
-----------------------------------------------
the sql query
select count(*) from content where book_name = 'John'
group by book_name, chapter_nr
in DB Browser returns 21 rows (which is the count of chapters)
the equivalent with ORMLite android:
long count = getHelper().getWordDao().queryBuilder()
.groupByRaw("book_name, chapter_nr")
.where()
.eq("book_name", book_name)
.countOf();
returns 828 rows (which is the count of verse numbers)
as far as I know the above code is translated to:
select count(*) from content
where book_name = 'John'
group by book_name, chapter_nr
result of this in DB Browser:
| count(*)
------------
1 | 828
2 | 430
3 | 653
...
21| 542
---------
21 Rows returned from: select count(*)...
so it seems to me that ORMLite returns the first row of the query as the result of countOf().
I've searched stackoverflow and google a lot. I found this question (and more interestingly the answer)
You can also count the number of rows in a custom query by calling the > countOf() method on the Where or QueryBuilder object.
// count the number of lines in this custom query
int numRows = dao.queryBuilder().where().eq("name", "Joe Smith").countOf();
this is (correct me if I'm wrong) exactly what I'm doing, but somehow I just get the wrong number of rows.
So... either I'm doing something wrong here or countOf() is not working the way it is supposed to.
Note: It's the same with groupBy instead of groupByRaw (according to ORMLite documentation joining groupBy's should work)
...
.groupBy("book_name")
.groupBy("chapter_nr")
.where(...)
.countOf()
EDIT: getWordDao returns from class Word:
#DatabaseTable(tableName = "content")
public class Word { ... }
returns 828 rows (which is the count of verse numbers)
This seems to be a limitation of the QueryBuilder.countOf() mechanism. It is expecting a single value and does not understand the addition of GROUP BY to the count query. You can tell that it doesn't because that method returns a single long.
If you want to extract the counts for each of the groups it looks like you will need to do a raw query check out the docs.

Modifying the contents of a result returned by a Oracle Sql query

One of our clients have requested information about customers.
I have written the query below, to extract the list of customers.
select * from customer;
Id | Name | Status
----+----------+-----------
1 Azam 0
2 Kapil 1
3 Osama 2
But the issue is the "Status" column, which is an enum from the java code(We have used hibernate for ORM).
Therefore, it is stored in the database as digits. The problem is, I have to replace the digits in the "Status"
column with constants before sending it to the customer, since the customer does not understand digits. I do this
by generating an excel file of the result set and amending the Status column values.
E.x.
In the Status column:
0 means Prospect, 1 means Active and 2 means Existing.
Question:
Is there a way to modify the result set returned from a query to obtain the following from Oracle alone:
select * from customer;
Id | Name | Status
----+----------+------------
1 Azam Prospect
2 Kapil Active
3 Osama Existing
I think you can use the decode function in the following way:
select id,name,decode(status,0,'Prospect',1,'Active',2,'Existing) from customer;
Regards
Giova
If you have a table containing the status details, then it should just be a matter of joining to that table and outputting the status description.
If you don't, and you know the status numbers/description won't change, then you could use a case statement:
select id, name, case when status = 0 then 'Prospect'
when status = 1 then 'Active'
when status = 2 then 'Existing'
...
else null -- can be omitted if null is the desired default, or change the null to the output required
end status
from customer;
In addition to other answers, if you want to store string values of Enum constants in the database, use this mapping
#Enumerated(value=EnumType.STRING)
private MyEnum myEnum;

Categories

Resources