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

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()
);
}

Related

Hibernate: column does not exist

When I try to load an Entity with Hibernate I get the following error in postgres-log:
ERROR: column appuser0_.device_token does not exist at character 35
STATEMENT: select appuser0_.id as id1_27_0_, appuser0_.device_token as device_t2_27_0_,....
The column device_token definitely exists - and if I copy-paste the whole logged statement and execute it in PGAdmin, I get the expected result.
So what do I forget? What is the difference between the Hibernate statement and the manually executed one?
This issue was caused by the multi tenant configuration so that the wrong DataSource has been chosen.
Depending on how you defined the query, the problem might be located somewhere else: For example, HQL Queries are using the "property-names" of the class, not the column names.
And if you have something like:
#Column("device_token")
private String deviceToken;
Then your HQL-Query should target "deviceToken" and not "device_token". We also encountered a similar error once: Hibernate was reporting "user_id" is missing, because we named the property "userId" with the underscored version for the column name only.
This might be not the problem for you but worth double checking it.

hbm2ddl.auto is not creating schema automatically when set to create [duplicate]

I am getting below exception, when trying to insert a batch of rows to an existing table
ORA-00942: table or view does not exist
I can confirm that the table exists in db and I can insert data to that table using oracle
sql developer. But when I try to insert rows using preparedstatement in java, its throwing table does not exist error.
Please find the stack trace of error below
java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1889)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout>>(OracleStatement.java:2709)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at quotecopy.DbConnection.insertIntoDestinationDb(DbConnection.java:591)
at quotecopy.QuoteCopier.main(QuoteCopier.java:72)
Can anyone suggest the reasons for this error ?
Update : Issue solved
There was no problem with my database connection properties or with my table or view name. The solution to the problem was very strange. One of the columns that I was trying insert was of Clob type. As I had a lot of trouble handling clob data in oracle db before, gave a try by replacing the clob setter with a temporary string setter and the same code executed with out any problems and all the rows were correctly inserted!!!.
ie. peparedstatement.setClob(columnIndex, clob)
was replaced with
peparedstatement.setString(columnIndex, "String")
Why an error table or view does exist error was throws for error in inserting clob data. Could anyone of you please explain ?
Thanks a lot for your answers and comments.
Oracle will also report this error if the table exists, but you don't have any privileges on it. So if you are sure that the table is there, check the grants.
There seems to be some issue with setCLOB() that causes an ORA-00942 under some circumstances when the target table does exist and is correctly privileged. I'm having this exact issue now, I can make the ORA-00942 go away by simply not binding the CLOB into the same table.
I've tried setClob() with a java.sql.Clob and setCLOB() with an oracle.jdbc.CLOB but with the same result.
As you say, if you bind as a string the problem goes away - but this then limits your data size to 4k.
From testing it seems to be triggered when a transaction is open on the session prior to binding the CLOB. I'll feed back when I've solved this...checking Oracle support.
There was no problem with my database connection properties or with my table or view name. The solution to the problem was very strange. One of the columns that I was trying insert was of Clob type. As I had a lot of trouble handling clob data in oracle db before, gave a try by replacing the clob setter with a temporary string setter and the same code executed with out any problems and all the rows were correctly inserted!!!.
ie. peparedstatement.setClob(columnIndex, clob)
was replaced with
peparedstatement.setString(columnIndex, "String")
#unbeli is right. Not having appropriate grants on a table will result in this error. For what it's worth, I recently experienced this. I was experiencing the exact problem that you described, I could execute insert statements through sql developer but would fail when using hibernate. I finally realized that my code was doing more than the obvious insert. Inserting into other tables that did not have appropriate grants. Adjusting grant privileges solved this for me.
Note: Don't have reputation to comment, otherwise this may have been a comment.
We experienced this issue on a BLOB column. Just in case anyone else lands on this question when encountering this error, here is how we resolved the issue:
We started out with this:
preparedStatement.setBlob(parameterIndex, resultSet.getBlob(columnName)); break;
We resolved the issue by changing that line to this:
java.sql.Blob blob = resultSet.getBlob(columnName);
if (blob != null) {
java.io.InputStream blobData = blob.getBinaryStream();
preparedStatement.setBinaryStream(parameterIndex, blobData);
} else {
preparedStatement.setBinaryStream(parameterIndex, null);
}
I found how to solve this problem without using JDBC's setString() method which limits the data to 4K.
What you need to do is to use preparedStatement.setClob(int parameterIndex, Reader reader). At least this is what that worked for me. Thought Oracle drivers converts data to character stream to insert, seems like not. Or something specific causing an error.
Using a characterStream seems to work for me. I am reading tables from one db and writing to another one using jdbc. And i was getting table not found error just like it is mentioned above. So this is how i solved the problem:
case Types.CLOB: //Using a switch statement for all columns, this is for CLOB columns
Clob clobData = resultSet.getClob(columnIndex); // The source db
if (clobData != null) {
preparedStatement.setClob(columnIndex, clobData.getCharacterStream());
} else {
preparedStatement.setClob(columnIndex, clobData);
}
clobData = null;
return;
All good now.
Is your script providing the schema name, or do you rely on the user logged into the database to select the default schema?
It might be that you do not name the schema and that you perform your batch with a system user instead of the schema user resulting in the wrong execution context for a script that would work fine if executed by the user that has the target schema set as default schema. Your best action would be to include the schema name in the insert statements:
INSERT INTO myschema.mytable (mycolums) VALUES ('myvalue')
update: Do you try to bind the table name as bound value in your prepared statement? That won't work.
It works for me:
Clob clob1;
while (rs.next()) {
rs.setString(1, rs.getString("FIELD_1"));
clob1 = rs.getClob("CLOB1");
if (clob1 != null) {
sta.setClob(2, clob1.getCharacterStream());
} else {
sta.setClob(2, clob1);
}
clob1 = null;
sta.setString(3, rs.getString("FIELD_3"));
}
Is it possible that you are doing INSERT for VARCHAR but doing an INSERT then an UPDATE for CLOB?
If so, you'll need to grant UPDATE permissions to the table in addition to INSERT.
See https://stackoverflow.com/a/64352414/1089967
Here I got the solution for the question. The problem is on glass fish if you are using it. When you create JNDI name make sure pool name is correct and pool name is the name of connection pool name that you are created.

Change Table names in derby database using entitymanager

I am using an APACHE DERBY database, and basing my database interactions on EntityManager, and I don't want to use JDBC class to build a query to change my tables' names (i just need to put a prefix to each new user to the application, but have the same structure of tables), such as:
//em stands for EntityManager object
Query tableNamesQuery= em.createNamedQuery("RENAME TABLE SCHEMA.EMP_ACT TO EMPLOYEE_ACT");
em.executeUpdate();
// ... rest of the function's work
// The command works from the database command prompt but i don't know how to use it in a program
//Or as i know you can't change system tables data, but here's the code
Query tableNamesQuery= em.createNamedQuery("UPDATE SYS.SYSTABLES SET TABLENAME='NEW_TABLE_NAME' WHERE TABLETYPE='T'");
em.executeUpdate();
// ... rest of the function's work
My questions are :
This syntax is correct?
Will it work?
Is there any other alternative?
Should I just use the SYS.SYSTABLES and find all the tables that has 'T' as tabletype and alter their name their, will it change the access name ?
I think you're looking for the RENAME TABLE statement: http://db.apache.org/derby/docs/10.10/ref/rrefsqljrenametablestatement.html
Don't just issue update statements against the system catalogs, you will corrupt your database.

"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.

Spring's JdbcDaoSupport (using MySQL Connector/J) fails after executing sql that adds FK

I am using Spring's JdbcDaoSupport class with a DriverManagerDataSource using the MySQL Connector/J 5.0 driver (driverClassName=com.mysql.jdbc.driver). allowMultiQueries is set to true in the url.
My application is an in-house tool we recently developed that executes sql scripts in a directory one-by-one (allows us to re-create our schema and reference table data for a given date, etc, but I digress). The sql scripts sometime contain multiple statements (hence allowMultiQueries), so one script can create a table, add indexes for that table, etc.
The problem happens when including a statement to add a foreign key constraint in one of these files. If I have a file that looks like...
--(column/constraint names are examples)
CREATE TABLE myTable (
fk1 BIGINT(19) NOT NULL,
fk2 BIGINT(19) NOT NULL,
PRIMARY KEY (fk1, fk2)
);
ALTER TABLE myTable ADD CONSTRAINT myTable_fk1
FOREIGN KEY (fk1)
REFERENCES myOtherTable (id)
;
ALTER TABLE myTable ADD CONSTRAINT myTable_fk2
FOREIGN KEY (fk2)
REFERENCES myOtherOtherTable (id)
;
then JdbcTemplate.execute throws an UncategorizedSqlException with the following error message and stack trace:
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [ THE SQL YOU SEE ABOVE LISTED HERE ];
SQL state [HY000]; error code [1005]; Can't create table 'myDatabase.myTable' (errno: 150); nested exception is java.sql.SQLException: Can't create table 'myDatabase.myTable' (errno: 150)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
and the table and foreign keys are not inserted.
Also, especially weird: if I take the foreign key statements out of the script I showed above and then place them in their own script that executes after (so I now have 1 script with just the create table statement, and 1 script with the add foreign key statements that executes after that) then what happens is:
tool executes create table script, works fine, table is created
tool executes add fk script, throws the same exception as seen above (except errno=121 this time), but the FKs actually get added (!!!)
In other words, when the create table/FK statements are in the same script then the exception is thrown and nothing is created, but when they are different scripts a nearly identical exception is thrown but both things get created.
Any help on this would be greatly appreciated. Please let me know if you'd like me to clarify anything more.
Some more info:
1) This only happens on my box. My coworker does not get the same problem.
2) The script that forces the tool to error works fine when executed from the mysql command line using the "script" command
My God.
http://bugs.mysql.com/bug.php?id=41635
and
[2nd link removed because spam filter isn't letting me add 2 links. Search Google for "mysql connector / j errno 150" and it's the 3rd result]
...
Looks like mySql5.1 has a bug with its jdbc connector where it bombs where an alter statement to add a FK is in a script with any other statement.
When I broke out my 3 statements into 3 scripts, it worked (the way I was trying before with the 2 fk statements in their own script still bombed because they were sharing a script!!). Also, my coworker is using MySql5.0, so it didn't affect him.
Holy Cow, that was a fun 5 hours.

Categories