HibernateException: Missing table: Metadata / Session on Oracle - java

When I try to map Oracle (11g) table with name "Metadata" or "Session" using JPA in Spring Boot application I get:
org.hibernate.HibernateException: Missing table: Metadata / Session
Session is restricted word in Oracle, but Metadata not.
Other tables works fine.
This shouldn't be a problem with my code, because when I move that DB to postgres, all work fine.

I was find source of problem.
When you want use table name like Metadata or Session in Oracle you must insert that name in additional quotes, then all work.
#Entity
#Table(name="\"Metadata\"")
#XmlRootElement
public class Metadata implements Serializable {
...
}

Related

Retrieving table metadata via Hibernate

Is there a simple way to retrieve table metadata (e.g. primary key and foreign keys) from a relational database, via Hibernate?
There are numerous XInformation interfaces in the package org.hibernate.tool.schema.extract.spi (e.g., TableInformation, PrimaryKeyInformation, ForeignKeyInformation), as well as an InformationExtractor interface, but no documented ways of how to instantiate them from a database session.
Using plain vanilla JSBC allows the retrieval of the metadata via
DatabaseMetaData metadata = connection.getMetaData();
Apparently the corresponding mechanism in Hibernate 5 is to register an org.hibernate.integrator.spi.Integrator object in the properties used to create SessionFactory objects to connect to the database, as discussed in this questiοn:
How to discover fully qualified table column from Hibernate MetadataSources
Is there any way of getting the above information as in JDBC, i.e. without modifying the session configuration?

Spring Boot Model Class only accessing Oracle table when using Synonym

I have a spring boot application and need to create a model class that accesses a database table.
Due to permissions configurations in the db, a SELECT only works using the username in front of the table name or using an Oracle Synonym.
In SQL Developer:
SELECT * FROM MYTABLE; // This doesn't work - ORA-00942: table or view does not exist
SELECT * FROM MYUSER.MYTABLE; // This works
SELECT * FROM MYTABLE_SYNONYM; // This works
In Oracle, MYTABLE_SYNONYM is a Public SYNONYM to MYTABLE.
So the two last SELECTS above are acessing the same MYTABLE table.
In the application:
#Entity
//#Table(name = "MYTABLE") // This doesn't work - ORA-00942: table or view does not exist
//#Table(name = "MYUSER.MYTABLE") // This DOESN'T work - ORA-00942: table or view does not exist
#Table(name = "MYTABLE_SYNONYM") // This works
public class MyClass implements Serializable {
....
}
My question is why #Table(name = "MYUSER.MYTABLE") is generating the "ORA-00942" error if SELECT * FROM MYUSER.MYTABLE works fine in SQL Developer?
In the application, the only way it works is using the Public SYNONYM.
But I wouldn't like to use a Synonym because it can cause confusion and difficulties for the application maintenance as the name is different from the actual table name.
Thanks.
The annotation #Table(name = "MYTABLE") doesn't work because the user that you are using to access the database has access to another schema as the default schema.
The annotation #Table(name = "MYUSER.MYTABLE") doesn't work because this is not the right syntax to access a table in a different schema. You need to use the annotation #Table(name="MYTABLE", schema="MYUSER") that explicitly says to use the schema MYUSER and search for a table named MYTABLE in that schema. This syntax is explained in the javadoc of the annotation Table:
(Optional) The schema of the table.
Defaults to the default schema for user.
The last annotation #Table(name = "MYTABLE_SYNONYM") because somebody defined a synonim MYTABLE_SYNONYM to access the table MYTABLE on the schema MYUSER. This is transparent from the point of view of the user accessing the db.

JPA: One Table with Two different databases

I want to store my table in two different databases, (for example: HyperSQL and MYSQL), but I can't duplicate table annotation like this:
#Entity(name="users")
#Table(name = "users", schema = "Users#HyperSQL_pu")
#Table(name = "users", schema = "Users#Mysql_pu")
public class UserEntitie implements Serializable {}
Have any idea, how can I do this without duplicating my bean class
This is why some people have recommended not to put schema information into annotations. Use orm.xml to specify schema information (schema name, table name, column name etc), and have one orm.xml per datastore that the system is deployed to. Clearly this means one EntityManagerFactory per datastore; you cannot have one class persisted into multiple datastores with the same EntityManagerFactory
Using annotations you can only specify something once, and would have to manually edit java files to redeploy.

Unit testing Hibernate with multiple database catalogs

I have an issue testing a Hibernate application which queries multiple catalogs/schemas.
The production database is Sybase and in addition to entities mapped to the default catalog/schema there are two entities mapped as below. There are therefore three catalogs in total.
#Table(catalog = "corp_ref_db", schema = "dbo", name = "WORKFORCE_V2")
public class EmployeeRecord implements Serializable {
}
#Table(catalog = "reference", schema = "dbo", name="cntry")
public class Country implements Serializable {
}
This all works in the application without any issues. However when unit testing my usual strategy is to use HSQL with hibernate's ddl flag set to auto and have dbunit populate the tables.
This all works fine when the tables are all in the same schema.
However, since adding these additional tables, testing is broken as the DDL will not run as HSQL only supports one catalog.
create table corp_ref_db.dbo.WORKFORCE_V2
user lacks privilege or object not found: CORP_REF_DB
If there were only two catalogs then I think it would maybe be possible to get round this by changing the default catalog and schema in the HSQL database to that one explicitly defined:
Is there any other in-memory database for which this might work or is there any strategy for getting the tests to run in HSQL.
I had thought of providing an orm.xml file which specified the default catalog and schema (overiding any annotations and having all the defined tables created in the default catalog/schema) however these overrides do not seem to be observed when the DDL is executed i.e. I get the same error as above.
Essentially, then I would like to run my existing tests and either somehow have the tables created as they are defined in the mappings or somehow override the catalog/schema definitions at the entity level.
I cannot think of any way to achieve either outcome. Any ideas?
I believe H2 supports catalogs. I haven't used them in it myself, but there's a CATALOGS table in the Information Schema.
I managed to achieve something like this in H2 via IGNORE_CATALOGS property and version 1.4.200
However, the url example from their docs did not seem to work for me, so I added a statement in my schema.xml:
SET IGNORE_CATALOGS = true;

How to support support SqlServer's ".." in HyperSQL?

tl;dr: I am trying to unit test some SqlServer queries which state the db name but they do not seem to work in HyperSql.
We are using Sql Server in production and I am trying to use HyperSQL as my database for unit testing. I am trying to test a class that creates SQL queries so stubbing out the database is not an option as having the queries parsed by a real database is part of the test.
Queries are supposed to be created in the form of SELECT * FROM EntAsdfDb007..Data_Table, although we can use the schema name ( 'db' ) if we wish.
From what I understand about the SELECT format for SqlServer, it allows you to specify the name of database followed by the name of schema. Also, you can drop the name of the database and have it inferred.
In HyperSqlDb I have been able to create the schema 'db' and create the necessary tables within it, and have been able to create tables within that schema but I have not be able to query with the database name even after setting the DB name using .setDatabaseName(). The exception I get is:
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: ENTASDFDB007
Just to be clear: I am unit-testing a class that uses SQL like SELECT * FROM EntAsdfDb007..Data_Table. I am trying to set up an instance of HyperSql for unit testing purposes but HyperSql seems to reject the syntax used.
That won't be possible.
HyperSQL cannot be changed to accept non-standard naming schemes.
It is possible. HSQLDB does have one catalog per database. The catalog name is PUBLIC by default, which you can change.
ALTER CATALOG PUBLIC RENAME TO EntAsdfDb007
You can then access your table with
SELECT * FROM EntAsdfDb007.db.Data_Table

Categories