HIbernate : More than one row with the given identifier was found - java

#Override
public Application getApplicationForId(Long applicationId) {
List<Application> applications = executeNamedQuery("applicationById", Application.class, applicationId);
return applications.isEmpty() ? null : applications.get(0);
}
while debugging in eclipse
return applications.isEmpty() ? null : applications.get(0);
these expression getting evaluated as
applications.isEmpty() -> false
applications.get(0) -> (id=171)
applications.size() -> 1
but after the execution of this line its throwing error
org.hibernate.HibernateException: More than one row with the given identifier was found: 263536,
Even its size is showing as 1, then still why and how its getting multiple rows after the execution.

I'm quite sure that this is due to eager fetching. So check you entity and remove the fetch=FetchType.EAGER.
Actually this is not caused by duplicate rows in the database, as it's obviously not possible to have duplicate primary keys. Instead this was caused by Hibernate looking up an object, and eagerly filling in a relationship. Hibernate assumed a single row would come back, but two came back because there were two objects associated with that relationship.

In my case the issue was,
while debugging when the execution is in the middle of the transaction, may be the purpose got served and forcibly stopped the server in the middle of the execution itself, as this has been forcibly stopped server, that cannot led the transaction to get rolledback and that end up in making the data dirty or corrupt in the database because before terminating the server some data might got inserted in db (chance of autoincrement of the primarykey).
Resetting the AutoIncrement value for the primary key of the table, resolved the issue.
1.Identify the table with dirty data (refer to stack trace )
2.Sort the column(primary key), check the highest value in the column(say somevalue).
3.use command
ALTER TABLE tablename AUTO_INCREMENT = somevalue+1

Related

org.hibernate.HibernateException: Missing table exception though MySQL table is present

I am connecting to a MySQL table using JPA Hibernate. But I am getting error in my Java code:
org.hibernate.HibernateException: Missing table
My table is present in MySQL database schema. I am not getting why missing table exception is thrown here. This is a newly created table. All other existing tables in the same schema are accessible from Hibernate. I saw similar posts with same error. But the answers there didn't help my cause. Can you please let me know what can be the issue here.
If table is present, then most likely it is user permission issue. This happens if you have created the table using a different MySQL user. Make sure the MySQL username/password that you are using in Hibernate is having access to the table. To test, login to MySQL console directly using Hibernate credential & run a select query on the table. If you see similar error as below, then you need to grant access to the table for the Hibernate user.
ERROR 1142 (42000): SELECT command denied to user
Source: http://www.w3spot.com/2020/10/how-to-solve-caused-by-hibernateexception-missing-table.html
Make sure the user has access to the table
Make sure names are equals in terms of case sensitivity
Make sure the schema name and table name are not misspelled
If you share more information about the issue, it would be easier to pinpoint the problem.
Chances are there is an inheritance scenario with a physical table that you assumed to be abstract.
To dig deeper you can put a breakpoint in org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl#getTablesInformation which calls extractor.getTable to see why your table is not returned as part of schema tables.
Rerun the app with the specified breakpoint and step through lines to get to the line which queries table names from the database metadat.
#Override
public TableInformation getTableInformation(QualifiedTableName tableName) {
if ( tableName.getObjectName() == null ) {
throw new IllegalArgumentException( "Passed table name cannot be null" );
}
return extractor.getTable(
tableName.getCatalogName(),
tableName.getSchemaName(),
tableName.getTableName()
);
}

Mysql Duplicate entry 'xxxxxxxx' for key(unique) 'xxxxxxxxxx'

I have a problem of updating a row. I have a column called serialNum with varchar(50) not null unique default null
When I get the response data from the partner company, i will update the row according to the unique serial_num (our company's serial num).
Sometimes update failed because of :
Duplicate entry 'xxxxxxxx' for key 'serialNum'
But the value to update is not exists when i search the whole table. It happens sometimes, not always, like about 10 times out of 300.
Why does this happen and how can I solve it?
below is the query i use to update:
String updateQuery = "update phone set serialNum=?, Order_state=?, Balance=? where Serial_num=" + resultSet.get("jno_cli");
PreparedStatement presta = con.prepareStatement(updateQuery);
presta.setString(1, resultSet.get("oid_goodsorder"));
presta.setString(2, "order success");
presta.setFloat(3, Float.valueOf(resultSet.get("leftmoney")));
presta.executeUpdate();
I think the reason is in resultSet.get("oid_goodsorder") where did you get this result? is 'oid_goodsorder' is unique? Did you always updates whole table?
If oid_goodsorder is unique, it is possible to have duplicates in serialNum, because you don't use bulk update, instead you update every record separately, therefore it is possible:
Before:
serialNum=11,22,33,44
oid_goodsorder=44,11,22,33
It tries to update first serialNum to 44, but 44 is exists!
But if you finish all update serialNum will be unique...
If you wants to get error rows you could disable set serialNum is not unique and check table for duplicating serialNum
If you don't have duplicating values try to use bulk update
Java - how to batch database inserts and updates

Handling Hibernate's error codes?

Consider an hypothetical User table:
-- postgres, but it could have been any other SQL database
CREATE TABLE User(
id SERIAL PRIMARY KEY,
mail VARCHAR(32) UNIQUE NOT NULL
);
Let's assume I attempt to add two users with the same mail:
session.save(new User(1, "xpto#gmail.com"));
session.save(new User(2, "xpto#gmail.com"));
and execute it through Hibernate. Hibernate will throw me an ConstraintViolationException:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
...
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "users_mail_key"
Detail: Key (mail)=(xpto#gmail.com) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
...
What I'd like to know is if there's some good way, other than having to manually parse the Exception's output text, to gather what is the reason of the error so I may correctly interpret and react to the problem.
I realize that this may actually be more of a Postgres Driver's problem than actually an Hibernate one, but I'm unsure at this stage so I thought it may opportune to ask in Hibernate's context.
So if you are able to get a value from getSQLState, you can handle the exception:
"All messages emitted by the PostgreSQL server are assigned five-character error codes that follow the SQL standard's conventions for "SQLSTATE" codes. Applications that need to know which error condition has occurred should usually test the error code, rather than looking at the textual error message."
From: http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
23505 = unique_violation
Note: In this link there is also the list.
Well, after looking at Postgres Driver's source code it seems the problem lies with Postgres and not with Hibernate. PSQLException will contain some information, although it certainly isn't as polished as I first assumed :(
} catch (PSQLException e) {
ServerErrorMessage m = e.getServerErrorMessage();
System.out.println(m.getColumn());
System.out.println(m.getConstraint());
System.out.println(m.getDatatype());
System.out.println(m.getDetail());
System.out.println(m.getFile());
System.out.println(m.getHint());
System.out.println(m.getInternalPosition());
System.out.println(m.getInternalQuery());
System.out.println(m.getLine());
System.out.println(m.getMessage());
System.out.println(m.getPosition());
System.out.println(m.getRoutine());
System.out.println(m.getSchema());
System.out.println(m.getSeverity());
System.out.println(m.getSQLState());
System.out.println(m.getTable());
System.out.println(m.getWhere());
}
prints
null
users_mail_key
null
Key (mail)=(xpto#gmail.com) already exists.
nbtinsert.c
null
0
null
398
duplicate key value violates unique constraint "users_mail_key"
0
_bt_check_unique
public
ERROR
23505
users
null

Hibernate to get max id and store it in memory

I am new to using hibernate. I have written the following code get the max id in my order table.
public int getOrderMaxUID() {
Session session = sessionFactory.getCurrentSession();
String query = "SELECT max(o.UID) FROM Order o";
List list = session.createQuery(query).list();
int maxOrderUID = ((Integer) list.get(0)).intValue();
return maxOrderUID;
}
and I call this method in my controller before I add a new record to the table.
orderService.getOrderMaxUID();
orderService.add(o);
The Issue : Records are added to our Order table by other processes as well. So to avoid Duplicate PK issue, I get the max id from the order table before inserting record. But I still get following error when other process add records
2013-04-04 09:27:24,841 WARN ["ajp-bio-8009"-exec-2] org.hibernate.util.JDBCExceptionReporter - SQL Error: 2627, SQLState: S1000
2013-04-04 09:27:24,841 ERROR ["ajp-bio-8009"-exec-2] org.hibernate.util.JDBCExceptionReporter - Violation of PRIMARY KEY constraint 'PK_Order'. Cannot insert duplicate key in object 'Order'. The duplicate key value is (1001508).
and
org.springframework.dao.DuplicateKeyException: Hibernate flushing: could not insert:
I want hibernate to store the id retrieved by getMaxOrderId() method in memory and use the next number as when adding new record.
Any help on this would be appreciated.
Why don't you get Hibernate to just generate the ID for you?
/** The id. */
#Id #GeneratedValue
private Long id;
EDIT:
You can create entries from multiple processes as long as you do it through hibernate and the id's will be adjusted accordingly.
Inserting into the database outside of hibernate however, will cause you issues. You may be able to use a Customer ID Generator to work around this. I found this example that may help
If you edit the database outside of hibernate, you may run into other problems as well (particularly if you use the second level cache for example)
If you use the same Session, you will run into issues caused by the first level cache as well.

"No row with the given identifier exists" although it DOES exist

I am using Hibernate and getting
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [#271]
What is pretty weird about this error is, that the object with the given id exists in the database. I inserted the problematic record in another run of the application. If I access it in the same run (i.e. same hibernate session) there seem to be no problems retrieving the data.
Just because it could be a fault of the mapping:
public class ProblemClass implements Persistent {
#ManyToOne(optional = false)
private MyDbObject myDbObject;
}
public class MyDbObject implements Persistent {
#OneToMany(mappedBy = "myDbObject")
private List<ProblemClass> problemClasses;
#ManyToOne(optional = false)
private ThirdClass thirdClass;
}
I have absolutely no clue even where to look at. Any hints highly appreciated!
Just to clarify:
The data was inserted in another RUN of the application. It is definitely in the database, as I can see it via an SQL-Query after the application terminated. And after THAT, i.e. when starting the application again, I get the error in the FIRST query of the database -- no deletion, no rollback involved.
Addition:
Because it was asked, here is the code to fetch the data:
public List<ProblemClass> getProblemClasses() {
Query query = session.createQuery("from ProblemClass");
return query.list();
}
And just to make it complete, here is the generic code to insert it (before fetching in another RUN of the application):
public void save(Persistent persistent) {
session.saveOrUpdate(persistent);
}
Eureka, I found it!
The problem was the following:
The data in the table ThirdClass was not persisted correctly. Since this data was referenced from MyDbObject via
optional = false
Hibernate made an inner join, thus returning an empty result for the join. Because the data was there if executed in one session (in the cache I guess), that made no problems.
MySQL does not enforce foreign key integrity, thus not complaining upon insertion of corrupt data.
Solution: optional = true or correct insertion of the data.
Possible reasons:
The row was inserted by the first session, but transaction was not committed when second session tried to access it.
First session is roll-backed due to some reason.
Sounds like your transaction inserting is rollbacked
Main reason behind this issue is data mismatch, for example i have entity mapping class called "X" and it has column "column1" and it has reference to the table "Y" column "column1" as below
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "column1", referencedColumnName = "column1")
public Y getColumn1() {
return Y;
}
In this if X table column1 has value but Y table column1 is not having the value. Here link will be failed.
This is the reason we will get Hibernate objectNotFound exception
This issue can also be resolved by creating proper data model like creating proper indexing and constraints (primary key/foreign key) ..
This might be your case, kindly check my answer on another post.
https://stackoverflow.com/a/40513787/6234057
I had the same Hibernate exception.
After debugging for sometime, i realized that the issue is caused by the Orphan child records.
As many are complaining, when they search the record it exists.
What i realized is that the issue is not because of the existence of the record but hibernate not finding it in the table, rather it is due to the Orphan child records.
The records which have reference to the non-existing parents!
What i did is, find the Foreign Key references corresponding to the Table linked to the Bean.
To find foreign key references in SQL developer
1.Save the below XML code into a file (fk_reference.xml)
<items>
<item type="editor" node="TableNode" vertical="true">
<title><![CDATA[FK References]]></title>
<query>
<sql>
<![CDATA[select a.owner,
a.table_name,
a.constraint_name,
a.status
from all_constraints a
where a.constraint_type = 'R'
and exists(
select 1
from all_constraints
where constraint_name=a.r_constraint_name
and constraint_type in ('P', 'U')
and table_name = :OBJECT_NAME
and owner = :OBJECT_OWNER)
order by table_name, constraint_name]]>
</sql>
</query>
</item>
2.Add the USER DEFINED extension to SQL Developer
Tools > Preferences
Database > User Defined Extensions
Click "Add Row" button
In Type choose "EDITOR", Location - where you saved the xml file above
Click "Ok" then restart SQL Developer
3.Navigate to any table and you will be able to see an additional tab next to SQL, labelled FK References, displaying FK information.
4.Reference
http://www.oracle.com/technetwork/issue-archive/2007/07-jul/o47sql-086233.html
How can I find which tables reference a given table in Oracle SQL Developer?
To find the Orphan records in all referred tables
select * from CHILD_TABLE
where FOREIGNKEY not in (select PRIMARYKEY from PARENT_TABLE);
Delete these Orphan records, Commit the changes and restart the server if required.
This solved my exception. You may try the same.
Please update your hibernate configuration file as given below:
property start tag name="hbm2ddl.auto" create/update property close tag
I have found that in Oracle this problem can also be caused by a permissions issue. The ProblemClass instance referred to by the MyDbObject instance may exist but have permissions that do not allow the current user to see it, even though the user can see the current MyDbObject.

Categories