I have a moderate size project using Spring Boot, and I am trying to create my first DataJpaTest with embedded H2, but I am getting the following exception:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table project.project.driver if exists" via JDBC Statemen
Caused by: org.h2.jdbc.JdbcSQLException: Schema "PROJECT" not found; SQL statement:
I have tried this and using a schema.sql, also this and using a test.properties in test/resources, and this other answer. But nothing worked. I am really baffled; this is the first time I face an issue in Spring Boot that I am not able to figure it out.
My entity classes are defined as:
#Entity
#Table(name = "table_name", schema = "project", catalog = "project")
#Lombok.Data
public class TableNameEntity { }
Any suggestion of how to force Hibernate to create the schema in H2?
You can pass a sql script which create schema in h2`s url:
jdbc:h2:mem:somedb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:create_schema.sql'
And in create_schema.sql would be something like this
CREATE SCHEMA IF NOT EXISTS project;
Related
My springboot trys to create a table that already exists in my mysql db
When I start springboot, it throws an exception
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table credential
Caused by: java.sql.SQLSyntaxErrorException: Table 'credential' already exists
Now I have an entity called credential
#Entity
#Table(name="credential")
public class CredentialEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
What I think is happening is that springboot sees the entity and try to create that table and throws an exception because the table already exists.
Is there a way to set something on the entity to stop springboot trying to create the table.
JPA does have that feature to auto create tables, after scanning your entity classes. According to the spring doc, the feature is controlled with the properties spring.jpa.generate-ddl(boolean) and spring.jpa.hibernate.ddl-auto(hibernate specific). Setting the first to false should stop table generation on startup.
Thank you everyone In my application.properties file I had the following line
spring.jpa.hibernate.ddl-auto=update.
I removed this and now springboot starts up without trying to create a new table per entity.
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.
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.
In my application there is an entity:
#Entity
#Table(schema = "hr", name = "personal_data")
public class PersonalData {
}
and connection string defined in Spring's application.properties:
spring.datasource.url=jdbc:mysql://localhost/mobile?UseUnicode=true&characterEncoding=utf8
If I invoke the following code:
TypedQuery<E> typedQuery = em.createQuery("from PersonalData pd where pd.employeeId = ?1", PersonalData.class);
typedQuery.setParameter(1, 123);
return typedQuery.getSingleResult();
it will result in this SQL:
select * from personal_data personalda0_ where personalda0_.employee_id=?
Which will fail with the exception
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'mobile.personal_data' doesn't exist
because the table personal_data is defined in the hr database and there is no such table in mobile.
This was working fine(i.e. table name in SQL was prefixed with database name) in Hibernate 4.3.13 and stopped when the application was migrated to Spring Boot 2.0 which uses Hibernate 5.2.14. Is there any way to achieve the old behaviour in Hibernate 5.x?
I can say that there is a misunderstanding between Hibernate 5 and MySQL, a long story here Hibernate 5.0.6 Ignores schema in MySQL
One Solution is proposed is to use the name of schema in the place of catalog so instead of :
#Table(schema = "hr", name = "personal_data")
^^^^^^
You can use :
#Table(catalog = "hr", name = "personal_data")
^^^^^^^
Also take a look at this :
5.0 Migration Guide
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 {
...
}