SQLGrammarException: ORA-00904 ("invalid identifier") - java

I'm getting an Oracle error / org.hibernate.exception.SQLGrammarException when I run a JUnit test against a Java class which uses JPA and Spring:
ORA-00904: "ALIAS"."COLUMN_NAME": invalid identifier
The odd thing is that the JUnit test works when run against a development database but fails when run against a database which I use for Continuous Integration builds (they are both Oracle databases).
Therefore, this would suggest that there's something missing or awry in the latter d/b. However, I have double- (and triple-)checked that the table referred to is identical in both databases and contains the column COLUMN_NAME that the error is referring to.
Further information - the DAO Java class invoked in the JUnit test uses a javax.persistence.EntityManager:
MyClass myObject = entityManager.find(MyClass.class, idNumber);
The MyClass JPA entity class maps onto the Oracle table:
#Configurable
#Entity
#Table(name = "MyTable", schema = "MySchema")
public class MyClass implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ")
#SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SEQ", allocationSize = 1)
#Column(name = "ID")
protected BigDecimal id;
#Column(name = "COLUMN_NAME")
private String columnName;
...
}
The column COLUMN_NAME in the database table in both databases is VARCHAR2(50) and nullable.
Versions:
Java - 1.6
Spring - 3.1.1
Oracle - 11.2.0.3.0
Thanks in advance for any assistance.

Found the problem. I found the query that Hibernate was creating (by adding
<property name="hibernate.show_sql" value="true" />
to my data-persistence.xml file) and tried to run it in the database where the test was failing. It transpires that in the entity Java class, the associated database table is defined like this:
#Table(name = "MyTable", schema = "MySchema")
... which works fine against the development d/b. However, the continuous integration database has all the tables created in a schema called something else, hence the error.
Thanks to everyone for their help.

Had the same issue. The reason was I missed adding the schema and the table name.
#Table(name = "Table", schema = "Schema")

Related

Spring Boot application doesn't create schemas for JPA #Table annotation

I want to have tables located in different database schemas. But unfortunately, I can't achieve this with Spring Boot. Here steps to reproduce it.
Create a new Spring Boot project on http://start.spring.io version 2.0.5 (with derby and PostgreSQL dependencies)
Create simple entity
#Entity
#Table(name = "my_table")
public class MyTable {
#Id Integer id;
}
Add only next property to the application.properties with value 'update' or 'create' (if you try 'create-drop' then you get another error described here: https://github.com/spring-projects/spring-boot/issues/7706#issuecomment-268798059). Now Derby datasource will be used by default.
spring.jpa.hibernate.ddl-auto=create
Run a generated test or main class. Be sure all works fine.
Modify the entity, add attribute schema to the #Table annotation. Now the entity looks like:
#Entity
#Table(name = "my_table", schema = "my_schema")
public class MyTable {
#Id Integer id;
}
Run a test (or main class). This time I get an error while Spring Boot initialization process "java.sql.SQLSyntaxErrorException: Schema 'MY_SCHEMA' does not exist":
Full log listing is available here: https://gist.github.com/asaushkin/8d767c92b2e7025dd359f7be43eefdd6
Check on PostgreSQL. This error reproduces on a PostgreSQL instance too. Without the 'schema' attribute Spring Boot app runs perfect, but as soon as this attribute appears on the #Table annotation the exceptions are thrown.
Full log is here: https://gist.github.com/asaushkin/dd0d677964556bf943c4f013d4785372
My question is: why are schemas not created by Spring Boot?
These options can't resolve this issue too:
spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas=true
spring.jpa.properties.hibernate.hbm2dll.create_namespaces=true
Links
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#configurations-hbmddl
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html#howto-configure-jpa-properties
Update (11 March 2019):
I've just check the current behavior of the issue. I wonder, but currently with Derby driver all works fine and the table is created with the specified schema. But in PostgreSQL an error continues exists.
Generated SQL (for PostgreSQL) is:
create table my_schema.my_table (id int4 not null, primary key (id))
Check that are you specifying the database dialect in the application.properties file or not for more check this thread.
Unable to get spring boot to automatically create database schema
I had the same problem with PostgreSQL and JPA (ERROR o.h.e.jdbc.spi.SqlExceptionHelper - ERROR: relation "schema.table" does not exist) and I figured out this solution.
In your entities classes, add escape characters \", between database element´s name. For instance:
Use this form:
#Table(name = "\"USUARIO\"", schema="\"INVENTARIODB\"")
Rather than a typical way
#Table(name = "USUARIO", schema="INVENTARIODB")
The same applies for columns names
#Column(name = "\"ID\"", nullable = false, updatable = false)
private Long id;
Rather than
#Column(name = "ID", nullable = false, updatable = false)
private Long id;
UPDATE:
I discovered the reason that was causing the problem. I used Valentina Studio to create my DB, if I use capital letters (MYTABLE), instead lower-case letters (mytable) to create my tables, I had to use double quotes inside SQL statements. This is because PostgreSQL is case sensitive. If you can´t change your database then use my last solution. Also is a good idea to enable spring.jpa.show-sql=true property, so you can see hibernate´s queries and know what´s going on.
Rename spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas to spring.jpa.properties.javax.persistence.create-database-schemas. In other words, remove '.schema-generation'.
I just had the same problem not with PostgreSQL but H2 - schemas weren't being created. But, as I've discovered, the problem is not with H2 (or, likely, PostgreSQL) but, rather, Hibernate (it deviates from the standard, regarding that nomenclature). That likely means that this solution will work for you too.

Hibernate having issues with sequence object - unable to call next val

I am using hibernate entity - and sequence generator with it.
My database is Oracle 12c.
In my sequence generator - it fetches value which is already present in table.
I tried looking out for issue - found one simmilar thread
Hibernate sequence nextVal resolved but not used (Oracle)
But still it did not help . The issue am facing is - it works some times and it does not work some times
Below is my code snippet -
#Entity
#Table(name="TABLE_NAME", schema = "SCHEMA")
#SequenceGenerator(name="TABLE_ID_SEQ_GEN", sequenceName="SCHEMA.TABLE_ID_SEQ",allocationSize=1)
public class ImportTransactionDataEntity {
#Id
#Column(name="TABLE_ID",unique=true,nullable=false)
#GeneratedValue(strategy=GenerationType.SEQUENCE,generator="TABLE_ID_SEQ_GEN" )
private int IDColumnPk;
ANy help is appreciated , thank you :)
According to Oracle documentation, the #SequenceGenerator should be added to the field, not to the class:
https://docs.oracle.com/cd/E16439_01/doc.1013/e13981/cmp30cfg001.htm#BCGGHADG
so something like:
#Entity
#Table(name="TABLE_NAME", schema = "SCHEMA")
public class ImportTransactionDataEntity {
#Id
#Column(name="TABLE_ID",unique=true,nullable=false)
#GeneratedValue(strategy=GenerationType.SEQUENCE,generator="TABLE_ID_SEQ_GEN" )
#SequenceGenerator(name="TABLE_ID_SEQ_GEN", sequenceName="SCHEMA.TABLE_ID_SEQ",allocationSize=1)
private int IDColumnPk;
This works for me.
try this
#Entity
#Table(name="TABLE_NAME")
#SequenceGenerator(name="TABLE_ID_SEQ_GEN",sequenceName="TABLE_ID_SEQ",allocationSize=1)
public class ImportTransactionDataEntity {
#Id
#Column(name="TABLE_ID",unique=true,nullable=false)
#GeneratedValue(strategy=GenerationType.AUTO,generator="TABLE_ID_SEQ_GEN" )
private int IDColumnPk;
it is stored in you database like this the last nummber is the last id used so dont worry about loosing count cause the database does that for you
well finally - i had come to a solution that i was already using oracle 12 C - decide to go with Identity column on the table it self .
NOTE - but the identity column is not available before Oracle 12c .
I ended up getting better performance also with some fraction , so this work around was sigh of relief for me
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "TABLE_ID", updatable = false, nullable = false)
private int IDColumnPk;

Creating sequence in Oracle Programmatically using JPA

I am using spring-boot-starter-data-jpa in my Spring boot project to handle DB stuff.
I want to create a sequence in Oracle programmatically.
I have seen many solution which create sequence using raw query but i want to create a sequence from the code. Is there anything i can do using JPA.
I also want to get this sequence number and return it to the caller.
Thanks in advance!!!
First of all, you have to allow Hibernate (one of the JPA implementations available in spring-boot-starter-data-jpa) create DDL statements, so in application.properties:
spring.jpa.hibernate.ddl-auto=create
Note that it is not recommended for production.
Next, annotate your entity in following way:
#Entity
public class SomeEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "my_generator")
#SequenceGenerator(name = "my_generator", sequenceName = "MY_SEQUENCE", allocationSize = 1)
private Long id;
//...
}
Once your application will start, hibernate based on your ddl-auto configuration will create the sequence for you:
Hibernate: create sequence MY_SEQUENCE start with 1 increment by 1
You can read more about ddl-autoconfigurations here.

Hibernate sequence not generated

Im working on a Spring (not Boot!) project, with Hibernate and PostgreSQL database. I also use Flyway for migration.
I use Flyway to generate the schema of the database, and insert initial data to it with given SQL scripts in my resources folder. For this reason, I excluded the hibernate.hbm2ddl.auto property from my hibernate.properties file.
On the startup, the schema is created and the data is inserted to the database, but my problem is, that this way Hibernate doesn't generate its sequence, and I cant save data from the application:
org.postgresql.util.PSQLException: ERROR: relation "hibernate_sequence" does not exist
What can I do with this?
As you didn't provide any code not sure what is wrong there, assume missing #SequenceGenerator annotation, I'll provide the one is working for me.
#Entity
#Table(name = "your_table")
#SequenceGenerator(name = "your_table_id_seq", sequenceName = "your_table_id_seq", allocationSize = 1)
public class YourTable implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "your_table_id_seq")
private Long id;
.
.
.
You need to create a sequence like this:
CREATE SEQUENCE hibernate_sequence START 1;

How to set the schema of #OneToMany autogenerated tables?

I want to put all of the following autogenerated tables into a specific schema.
#Entity
#Table(name = "master_table", schema = "test")
public class MasterTable {
#OneToMany
private List<VideoEntity> videos;
#Entity
#Table(name = "video_entity", schema = "test")
public static class VideoEntity {
}
}
Result: there are the two entity tables in test schema, but also one in the public schema called master_table_videos for the list mapping.
Question: how can I tell hibernate to also put the list-mapping table in the same schema than the others?
I think you should use the #JoinTable annotation, at least that allows to set the schema name in standard JPA. Check the JavaDoc for Java EE 7 or Java EE 6.
So it would be something like #JoinTable(name = "master_to_videos", schema = "test" ), and you could also specify the name of the join column if required.
Hibernate will create the table in whichever persistence.xml the entity is defined in. So if MasterTable and VideoEntity are both in persistence.xml, it will create both tables in the configured data schema.
I agree with Hein Blöd i tested the #joinTable annotation after any other annotation like #ManyToOne #OneToMany ... as for your example it becomes like this
#OneToMany
#JoinTable(schema = "testSchema" )
private List<VideoEntity> videos;
testSchema is interpreted by Hibernate as test-schema
i know this is for an old question i'm writing this so that any one
right now can find the correct answer i search the internet and this is the first question i found.

Categories